| Index: components/policy/core/common/policy_map.cc
|
| diff --git a/components/policy/core/common/policy_map.cc b/components/policy/core/common/policy_map.cc
|
| index febad177ecbe2b902f027574c9f444d25c819b2c..162d5ac1c9dfcb270e91b228ffc569e85a6424b7 100644
|
| --- a/components/policy/core/common/policy_map.cc
|
| +++ b/components/policy/core/common/policy_map.cc
|
| @@ -56,6 +56,37 @@ bool PolicyMap::Entry::Equals(const PolicyMap::Entry& other) const {
|
| other.external_data_fetcher);
|
| }
|
|
|
| +PolicyMap::PolicyMapKey::PolicyMapKey() {
|
| +}
|
| +
|
| +PolicyMap::PolicyMapKey::PolicyMapKey(const std::string& name_in)
|
| + : name(name_in) {
|
| +}
|
| +
|
| +PolicyMap::PolicyMapKey::PolicyMapKey(const std::string& name_in,
|
| + PolicyLevel level_in)
|
| + : name(name_in), level(level_in) {
|
| +}
|
| +
|
| +bool PolicyMap::PolicyMapKey::operator==(const PolicyMapKey& other) const {
|
| + return name == other.name && level == other.level;
|
| +}
|
| +
|
| +bool PolicyMap::PolicyMapKey::operator<(const PolicyMapKey& other) const {
|
| + int name_comp = name.compare(other.name);
|
| + if (name_comp)
|
| + return name_comp < 0;
|
| + // Compare policy level. Should be consistent with has_higher_priority_than().
|
| + return level > other.level;
|
| +}
|
| +
|
| +int PolicyMap::PolicyMapKey::compare(const PolicyMapKey& other) const {
|
| + int name_comp = name.compare(other.name);
|
| + if (name_comp)
|
| + return name_comp;
|
| + return level > other.level ? -1 : (level < other.level ? 1 : 0);
|
| +}
|
| +
|
| PolicyMap::PolicyMap() {
|
| }
|
|
|
| @@ -64,13 +95,15 @@ PolicyMap::~PolicyMap() {
|
| }
|
|
|
| const PolicyMap::Entry* PolicyMap::Get(const std::string& policy) const {
|
| - PolicyMapType::const_iterator entry = map_.find(policy);
|
| - return entry == map_.end() ? NULL : &entry->second;
|
| + const_iterator entry = lower_bound(policy);
|
| + return entry == map_.end() || entry->first.name != policy ?
|
| + nullptr : &entry->second;
|
| }
|
|
|
| const base::Value* PolicyMap::GetValue(const std::string& policy) const {
|
| - PolicyMapType::const_iterator entry = map_.find(policy);
|
| - return entry == map_.end() ? NULL : entry->second.value;
|
| + const_iterator entry = lower_bound(policy);
|
| + return entry == map_.end() || entry->first.name != policy ?
|
| + nullptr : entry->second.value;
|
| }
|
|
|
| void PolicyMap::Set(const std::string& policy,
|
| @@ -79,7 +112,7 @@ void PolicyMap::Set(const std::string& policy,
|
| PolicySource source,
|
| base::Value* value,
|
| ExternalDataFetcher* external_data_fetcher) {
|
| - Entry& entry = map_[policy];
|
| + Entry& entry = map_[PolicyMapKey(policy, level)];
|
| entry.DeleteOwnedMembers();
|
| entry.level = level;
|
| entry.scope = scope;
|
| @@ -89,10 +122,14 @@ void PolicyMap::Set(const std::string& policy,
|
| }
|
|
|
| void PolicyMap::Erase(const std::string& policy) {
|
| - PolicyMapType::iterator it = map_.find(policy);
|
| - if (it != map_.end()) {
|
| + PolicyMapType::iterator it = lower_bound(policy);
|
| + PolicyMapType::iterator end_it = map_.end();
|
| + while (it != map_.end() && it->first.name == policy) {
|
| + PolicyMapType::iterator next_it = it;
|
| + ++next_it;
|
| it->second.DeleteOwnedMembers();
|
| map_.erase(it);
|
| + it = next_it;
|
| }
|
| }
|
|
|
| @@ -104,7 +141,7 @@ void PolicyMap::CopyFrom(const PolicyMap& other) {
|
| Clear();
|
| for (const_iterator it = other.begin(); it != other.end(); ++it) {
|
| const Entry& entry = it->second;
|
| - Set(it->first, entry.level, entry.scope, entry.source,
|
| + Set(it->first.name, it->first.level, entry.scope, entry.source,
|
| entry.value->DeepCopy(),
|
| entry.external_data_fetcher
|
| ? new ExternalDataFetcher(*entry.external_data_fetcher)
|
| @@ -120,13 +157,13 @@ scoped_ptr<PolicyMap> PolicyMap::DeepCopy() const {
|
|
|
| void PolicyMap::MergeFrom(const PolicyMap& other) {
|
| for (const_iterator it = other.begin(); it != other.end(); ++it) {
|
| - const Entry* entry = Get(it->first);
|
| - if (!entry || it->second.has_higher_priority_than(*entry)) {
|
| - Set(it->first, it->second.level, it->second.scope, it->second.source,
|
| + const_iterator this_it = map_.find(it->first);
|
| + if (this_it == map_.end() ||
|
| + it->second.has_higher_priority_than(this_it->second)) {
|
| + Set(it->first.name, it->first.level, it->second.scope, it->second.source,
|
| it->second.value->DeepCopy(),
|
| it->second.external_data_fetcher
|
| - ? new ExternalDataFetcher(
|
| - *it->second.external_data_fetcher)
|
| + ? new ExternalDataFetcher(*it->second.external_data_fetcher)
|
| : nullptr);
|
| }
|
| }
|
| @@ -144,7 +181,7 @@ void PolicyMap::LoadFrom(
|
| }
|
|
|
| void PolicyMap::GetDifferingKeys(const PolicyMap& other,
|
| - std::set<std::string>* differing_keys) const {
|
| + std::set<PolicyMap::PolicyMapKey>* differing_keys) const {
|
| // Walk over the maps in lockstep, adding everything that is different.
|
| const_iterator iter_this(begin());
|
| const_iterator iter_other(other.begin());
|
| @@ -171,10 +208,19 @@ void PolicyMap::GetDifferingKeys(const PolicyMap& other,
|
| differing_keys->insert(iter_other->first);
|
| }
|
|
|
| +void PolicyMap::GetDifferingKeyNames(const PolicyMap& other,
|
| + std::set<std::string>* differing_key_names) const {
|
| + std::set<PolicyMap::PolicyMapKey> differing_keys;
|
| + GetDifferingKeys(other, &differing_keys);
|
| + for (const auto& key : differing_keys) {
|
| + differing_key_names->insert(key.name);
|
| + }
|
| +}
|
| +
|
| void PolicyMap::FilterLevel(PolicyLevel level) {
|
| PolicyMapType::iterator iter(map_.begin());
|
| while (iter != map_.end()) {
|
| - if (iter->second.level != level) {
|
| + if (iter->first.level != level) {
|
| iter->second.DeleteOwnedMembers();
|
| map_.erase(iter++);
|
| } else {
|
| @@ -204,6 +250,19 @@ PolicyMap::const_iterator PolicyMap::end() const {
|
| return map_.end();
|
| }
|
|
|
| +void PolicyMap::next_dominant(PolicyMap::const_iterator* it) const {
|
| + DCHECK((*it) != map_.end());
|
| + const std::string& prev_name = (*it)->first.name;
|
| + do {
|
| + ++(*it);
|
| + } while ((*it) != map_.end() && (*it)->first.name == prev_name);
|
| +}
|
| +
|
| +void PolicyMap::next_all(PolicyMap::const_iterator* it) const {
|
| + DCHECK((*it) != map_.end());
|
| + ++(*it);
|
| +}
|
| +
|
| void PolicyMap::Clear() {
|
| for (PolicyMapType::iterator it = map_.begin(); it != map_.end(); ++it)
|
| it->second.DeleteOwnedMembers();
|
| @@ -216,4 +275,16 @@ bool PolicyMap::MapEntryEquals(const PolicyMap::PolicyMapType::value_type& a,
|
| return a.first == b.first && a.second.Equals(b.second);
|
| }
|
|
|
| +PolicyMap::PolicyMapType::iterator PolicyMap::lower_bound(
|
| + const std::string& policy) {
|
| + PolicyMapKey key(policy);
|
| + return map_.lower_bound(key);
|
| +}
|
| +
|
| +PolicyMap::const_iterator PolicyMap::lower_bound(
|
| + const std::string& policy) const {
|
| + PolicyMapKey key(policy);
|
| + return map_.lower_bound(key);
|
| +}
|
| +
|
| } // namespace policy
|
|
|