Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sync/syncable/parent_child_index.h" | 5 #include "sync/syncable/parent_child_index.h" |
| 6 | 6 |
| 7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
| 8 | 8 |
| 9 #include "sync/syncable/entry_kernel.h" | 9 #include "sync/syncable/entry_kernel.h" |
| 10 #include "sync/syncable/syncable_id.h" | 10 #include "sync/syncable/syncable_id.h" |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 DCHECK(!b->ref(UNIQUE_POSITION).IsValid()); | 36 DCHECK(!b->ref(UNIQUE_POSITION).IsValid()); |
| 37 // Sort by META_HANDLE to ensure consistent order for testing. | 37 // Sort by META_HANDLE to ensure consistent order for testing. |
| 38 return a->ref(META_HANDLE) < b->ref(META_HANDLE); | 38 return a->ref(META_HANDLE) < b->ref(META_HANDLE); |
| 39 } | 39 } |
| 40 } | 40 } |
| 41 | 41 |
| 42 ParentChildIndex::ParentChildIndex() { | 42 ParentChildIndex::ParentChildIndex() { |
| 43 // Pre-allocate these two vectors to the number of model types. | 43 // Pre-allocate these two vectors to the number of model types. |
| 44 model_type_root_ids_.resize(MODEL_TYPE_COUNT); | 44 model_type_root_ids_.resize(MODEL_TYPE_COUNT); |
| 45 type_root_child_sets_.resize(MODEL_TYPE_COUNT); | 45 type_root_child_sets_.resize(MODEL_TYPE_COUNT); |
| 46 bytes_used_ = | |
| 47 MODEL_TYPE_COUNT * (sizeof(Id) + sizeof(OrderedChildSet*)) + sizeof(this); | |
| 46 } | 48 } |
| 47 | 49 |
| 48 ParentChildIndex::~ParentChildIndex() { | 50 ParentChildIndex::~ParentChildIndex() { |
| 49 for (int i = 0; i < MODEL_TYPE_COUNT; i++) { | 51 for (int i = 0; i < MODEL_TYPE_COUNT; i++) { |
| 50 // Normally all OrderedChildSet instances in |type_root_child_sets_| | 52 // Normally all OrderedChildSet instances in |type_root_child_sets_| |
| 51 // are shared with |parent_children_map_|. Null out shared instances and | 53 // are shared with |parent_children_map_|. Null out shared instances and |
| 52 // ScopedVector will take care of the ones that are not shared (if any). | 54 // ScopedVector will take care of the ones that are not shared (if any). |
| 53 if (!model_type_root_ids_[i].IsNull()) { | 55 if (!model_type_root_ids_[i].IsNull()) { |
| 54 DCHECK_EQ(type_root_child_sets_[i], | 56 DCHECK_EQ(type_root_child_sets_[i], |
| 55 parent_children_map_.find(model_type_root_ids_[i])->second); | 57 parent_children_map_.find(model_type_root_ids_[i])->second); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 76 | 78 |
| 77 if (ShouldUseParentId(parent_id, model_type)) { | 79 if (ShouldUseParentId(parent_id, model_type)) { |
| 78 // Hierarchical type, lookup child set in the map. | 80 // Hierarchical type, lookup child set in the map. |
| 79 DCHECK(!parent_id.IsNull()); | 81 DCHECK(!parent_id.IsNull()); |
| 80 ParentChildrenMap::iterator it = parent_children_map_.find(parent_id); | 82 ParentChildrenMap::iterator it = parent_children_map_.find(parent_id); |
| 81 if (it != parent_children_map_.end()) { | 83 if (it != parent_children_map_.end()) { |
| 82 siblings = it->second; | 84 siblings = it->second; |
| 83 } else { | 85 } else { |
| 84 siblings = new OrderedChildSet(); | 86 siblings = new OrderedChildSet(); |
| 85 parent_children_map_.insert(std::make_pair(parent_id, siblings)); | 87 parent_children_map_.insert(std::make_pair(parent_id, siblings)); |
| 88 bytes_used_ += parent_id.value().capacity() + sizeof(OrderedChildSet); | |
|
stanisc
2016/07/06 21:50:32
I would prefer to not mix the code for the size es
ssid
2016/07/19 22:10:35
counting the usage on demand.
| |
| 86 } | 89 } |
| 87 } else { | 90 } else { |
| 88 // Non-hierarchical type, return a pre-defined collection by type. | 91 // Non-hierarchical type, return a pre-defined collection by type. |
| 89 siblings = GetOrCreateModelTypeChildSet(model_type); | 92 siblings = GetOrCreateModelTypeChildSet(model_type); |
| 90 } | 93 } |
| 91 | 94 |
| 92 // If this is one of type root folder for a non-hierarchical type, associate | 95 // If this is one of type root folder for a non-hierarchical type, associate |
| 93 // its ID with the model type and the type's pre-defined child set with the | 96 // its ID with the model type and the type's pre-defined child set with the |
| 94 // type root ID. | 97 // type root ID. |
| 95 // TODO(stanisc): crbug/438313: Just TypeSupportsHierarchy condition should | 98 // TODO(stanisc): crbug/438313: Just TypeSupportsHierarchy condition should |
| 96 // theoretically be sufficient but in practice many tests don't properly | 99 // theoretically be sufficient but in practice many tests don't properly |
| 97 // initialize entries so TypeSupportsHierarchy ends up failing. Consider | 100 // initialize entries so TypeSupportsHierarchy ends up failing. Consider |
| 98 // tweaking TypeSupportsHierarchy and fixing all related test code. | 101 // tweaking TypeSupportsHierarchy and fixing all related test code. |
| 99 if (parent_id.IsRoot() && entry->ref(IS_DIR) && | 102 if (parent_id.IsRoot() && entry->ref(IS_DIR) && |
| 100 syncer::IsRealDataType(model_type) && | 103 syncer::IsRealDataType(model_type) && |
| 101 !TypeSupportsHierarchy(model_type)) { | 104 !TypeSupportsHierarchy(model_type)) { |
| 102 const Id& type_root_id = entry->ref(ID); | 105 const Id& type_root_id = entry->ref(ID); |
| 103 // Disassociate the type root child set with the previous ID if any. | 106 // Disassociate the type root child set with the previous ID if any. |
| 104 const Id& prev_type_root_id = model_type_root_ids_[model_type]; | 107 const Id& prev_type_root_id = model_type_root_ids_[model_type]; |
| 105 if (!prev_type_root_id.IsNull()) { | 108 if (!prev_type_root_id.IsNull()) { |
| 106 ParentChildrenMap::iterator it = | 109 ParentChildrenMap::iterator it = |
| 107 parent_children_map_.find(prev_type_root_id); | 110 parent_children_map_.find(prev_type_root_id); |
| 108 if (it != parent_children_map_.end()) { | 111 if (it != parent_children_map_.end()) { |
| 109 // If the entry exists in the map it must already have the same | 112 // If the entry exists in the map it must already have the same |
| 110 // model type specific child set. This child set will be re-inserted | 113 // model type specific child set. This child set will be re-inserted |
| 111 // in the map under the new ID below so it is safe to simply erase | 114 // in the map under the new ID below so it is safe to simply erase |
| 112 // the entry here. | 115 // the entry here. |
| 113 DCHECK_EQ(it->second, GetModelTypeChildSet(model_type)); | 116 DCHECK_EQ(it->second, GetModelTypeChildSet(model_type)); |
| 117 bytes_used_ -= | |
| 118 2 * it->first.value().capacity() + sizeof(OrderedChildSet*); | |
| 114 parent_children_map_.erase(it); | 119 parent_children_map_.erase(it); |
| 115 } | 120 } |
| 116 } | 121 } |
| 117 // Store the new type root ID and associate the child set. | 122 // Store the new type root ID and associate the child set. |
| 118 // Note that the child set isn't owned by the map in this case. | 123 // Note that the child set isn't owned by the map in this case. |
| 119 model_type_root_ids_[model_type] = type_root_id; | 124 model_type_root_ids_[model_type] = type_root_id; |
| 120 parent_children_map_.insert( | 125 parent_children_map_.insert( |
| 121 std::make_pair(type_root_id, GetOrCreateModelTypeChildSet(model_type))); | 126 std::make_pair(type_root_id, GetOrCreateModelTypeChildSet(model_type))); |
| 127 bytes_used_ += | |
| 128 2 * type_root_id.value().capacity() + sizeof(OrderedChildSet*); | |
|
stanisc
2016/07/06 21:50:32
This doesn't take into account sizeof(Id) which sh
ssid
2016/07/19 22:10:35
Oh the 2 is multiplied not for the encoding. It is
| |
| 122 } | 129 } |
| 123 | 130 |
| 124 // Finally, insert the entry in the child set. | 131 // Finally, insert the entry in the child set. |
| 132 bytes_used_ += sizeof(EntryKernel*); | |
|
stanisc
2016/07/06 21:50:32
This is a bit simplistic. See this: http://info.pr
ssid
2016/07/19 22:10:35
Fixed with more accurate values.
| |
| 125 return siblings->insert(entry).second; | 133 return siblings->insert(entry).second; |
| 126 } | 134 } |
| 127 | 135 |
| 128 // Like the other containers used to help support the syncable::Directory, this | 136 // Like the other containers used to help support the syncable::Directory, this |
| 129 // one does not own any EntryKernels. This function removes references to the | 137 // one does not own any EntryKernels. This function removes references to the |
| 130 // given EntryKernel but does not delete it. | 138 // given EntryKernel but does not delete it. |
| 131 void ParentChildIndex::Remove(EntryKernel* e) { | 139 void ParentChildIndex::Remove(EntryKernel* e) { |
| 132 OrderedChildSet* siblings = nullptr; | 140 OrderedChildSet* siblings = nullptr; |
| 133 ModelType model_type = e->GetModelType(); | 141 ModelType model_type = e->GetModelType(); |
| 134 const Id& parent_id = e->ref(PARENT_ID); | 142 const Id& parent_id = e->ref(PARENT_ID); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 145 } else { | 153 } else { |
| 146 // Non-hierarchical type, return a pre-defined child set by type. | 154 // Non-hierarchical type, return a pre-defined child set by type. |
| 147 siblings = type_root_child_sets_[model_type]; | 155 siblings = type_root_child_sets_[model_type]; |
| 148 } | 156 } |
| 149 | 157 |
| 150 OrderedChildSet::iterator j = siblings->find(e); | 158 OrderedChildSet::iterator j = siblings->find(e); |
| 151 DCHECK(j != siblings->end()); | 159 DCHECK(j != siblings->end()); |
| 152 | 160 |
| 153 // Erase the entry from the child set. | 161 // Erase the entry from the child set. |
| 154 siblings->erase(j); | 162 siblings->erase(j); |
| 163 bytes_used_ -= sizeof(EntryKernel*); | |
| 155 // If the set is now empty and isn't shareable with |type_root_child_sets_|, | 164 // If the set is now empty and isn't shareable with |type_root_child_sets_|, |
| 156 // erase it from the map. | 165 // erase it from the map. |
| 157 if (siblings->empty() && should_erase) { | 166 if (siblings->empty() && should_erase) { |
| 158 delete siblings; | 167 delete siblings; |
| 168 bytes_used_ -= it->first.value().capacity() + sizeof(OrderedChildSet); | |
| 159 parent_children_map_.erase(it); | 169 parent_children_map_.erase(it); |
| 160 } | 170 } |
| 161 } | 171 } |
| 162 | 172 |
| 163 bool ParentChildIndex::Contains(EntryKernel *e) const { | 173 bool ParentChildIndex::Contains(EntryKernel *e) const { |
| 164 const OrderedChildSet* siblings = GetChildSet(e); | 174 const OrderedChildSet* siblings = GetChildSet(e); |
| 165 return siblings && siblings->count(e) > 0; | 175 return siblings && siblings->count(e) > 0; |
| 166 } | 176 } |
| 167 | 177 |
| 168 const OrderedChildSet* ParentChildIndex::GetChildren(const Id& id) const { | 178 const OrderedChildSet* ParentChildIndex::GetChildren(const Id& id) const { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 type_root_child_sets_[model_type] = new OrderedChildSet(); | 240 type_root_child_sets_[model_type] = new OrderedChildSet(); |
| 231 return type_root_child_sets_[model_type]; | 241 return type_root_child_sets_[model_type]; |
| 232 } | 242 } |
| 233 | 243 |
| 234 const Id& ParentChildIndex::GetModelTypeRootId(ModelType model_type) const { | 244 const Id& ParentChildIndex::GetModelTypeRootId(ModelType model_type) const { |
| 235 return model_type_root_ids_[model_type]; | 245 return model_type_root_ids_[model_type]; |
| 236 } | 246 } |
| 237 | 247 |
| 238 } // namespace syncable | 248 } // namespace syncable |
| 239 } // namespace syncer | 249 } // namespace syncer |
| OLD | NEW |