OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #ifndef BASE_ID_MAP_H_ | 5 #ifndef BASE_ID_MAP_H_ |
6 #define BASE_ID_MAP_H_ | 6 #define BASE_ID_MAP_H_ |
7 | 7 |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <map> | |
10 #include <memory> | 11 #include <memory> |
11 #include <set> | 12 #include <set> |
12 #include <type_traits> | 13 #include <type_traits> |
14 #include <unordered_map> | |
13 #include <utility> | 15 #include <utility> |
14 | 16 |
15 #include "base/containers/hash_tables.h" | 17 #include "base/containers/flat_set.h" |
16 #include "base/logging.h" | 18 #include "base/logging.h" |
17 #include "base/macros.h" | 19 #include "base/macros.h" |
18 #include "base/sequence_checker.h" | 20 #include "base/sequence_checker.h" |
19 | 21 |
20 // This object maintains a list of IDs that can be quickly converted to | 22 // This object maintains a list of IDs that can be quickly converted to |
21 // pointers to objects. It is implemented as a hash table, optimized for | 23 // pointers to objects. It is implemented as a hash table, optimized for |
22 // relatively small data sets (in the common case, there will be exactly one | 24 // relatively small data sets (in the common case, there will be exactly one |
23 // item in the list). | 25 // item in the list). |
24 // | 26 // |
25 // Items can be inserted into the container with arbitrary ID, but the caller | 27 // Items can be inserted into the container with arbitrary ID, but the caller |
26 // must ensure they are unique. Inserting IDs and relying on automatically | 28 // must ensure they are unique. Inserting IDs and relying on automatically |
27 // generated ones is not allowed because they can collide. | 29 // generated ones is not allowed because they can collide. |
28 | 30 |
29 // The map's value type (the V param) can be any dereferenceable type, such as a | 31 // The map's value type (the V param) can be any dereferenceable type, such as a |
30 // raw pointer or smart pointer | 32 // raw pointer or smart pointer |
31 template <typename V, typename K = int32_t> | 33 template <typename V, typename K = int32_t> |
32 class IDMap final { | 34 class IDMap final { |
33 public: | 35 public: |
34 using KeyType = K; | 36 using KeyType = K; |
35 | 37 |
36 private: | 38 private: |
37 using T = typename std::remove_reference<decltype(*V())>::type; | 39 using T = typename std::remove_reference<decltype(*V())>::type; |
38 using HashTable = base::hash_map<KeyType, V>; | 40 |
41 // Requires stable iterators so flat_map and small_map can't be used. | |
42 // unordered_map is not used due to high memory overhead for small containers. | |
43 using HashTable = std::unordered_map<KeyType, V>; | |
Łukasz Anforowicz
2017/04/24 18:46:10
The declaration on previous line (using |std::unor
brettw
2017/04/25 23:32:36
I misunderstood the implementation and stable iter
Łukasz Anforowicz
2017/04/25 23:49:01
Thanks. I see that the CL switches |removed_ids_|
brettw
2017/04/26 20:51:57
IDMap is a template used in a bunch of places for
| |
39 | 44 |
40 public: | 45 public: |
41 IDMap() : iteration_depth_(0), next_id_(1), check_on_null_data_(false) { | 46 IDMap() : iteration_depth_(0), next_id_(1), check_on_null_data_(false) { |
42 // A number of consumers of IDMap create it on one thread but always | 47 // A number of consumers of IDMap create it on one thread but always |
43 // access it from a different, but consistent, thread (or sequence) | 48 // access it from a different, but consistent, thread (or sequence) |
44 // post-construction. The first call to CalledOnValidSequence() will re-bind | 49 // post-construction. The first call to CalledOnValidSequence() will re-bind |
45 // it. | 50 // it. |
46 sequence_checker_.DetachFromSequence(); | 51 sequence_checker_.DetachFromSequence(); |
47 } | 52 } |
48 | 53 |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
229 removed_ids_.clear(); | 234 removed_ids_.clear(); |
230 } | 235 } |
231 | 236 |
232 // Keep track of how many iterators are currently iterating on us to safely | 237 // Keep track of how many iterators are currently iterating on us to safely |
233 // handle removing items during iteration. | 238 // handle removing items during iteration. |
234 int iteration_depth_; | 239 int iteration_depth_; |
235 | 240 |
236 // Keep set of IDs that should be removed after the outermost iteration has | 241 // Keep set of IDs that should be removed after the outermost iteration has |
237 // finished. This way we manage to not invalidate the iterator when an element | 242 // finished. This way we manage to not invalidate the iterator when an element |
238 // is removed. | 243 // is removed. |
239 std::set<KeyType> removed_ids_; | 244 base::flat_set<KeyType> removed_ids_; |
Łukasz Anforowicz
2017/04/24 18:46:10
nit: I wonder if you could please expand the CL de
| |
240 | 245 |
241 // The next ID that we will return from Add() | 246 // The next ID that we will return from Add() |
242 KeyType next_id_; | 247 KeyType next_id_; |
243 | 248 |
244 HashTable data_; | 249 HashTable data_; |
245 | 250 |
246 // See description above setter. | 251 // See description above setter. |
247 bool check_on_null_data_; | 252 bool check_on_null_data_; |
248 | 253 |
249 base::SequenceChecker sequence_checker_; | 254 base::SequenceChecker sequence_checker_; |
250 | 255 |
251 DISALLOW_COPY_AND_ASSIGN(IDMap); | 256 DISALLOW_COPY_AND_ASSIGN(IDMap); |
252 }; | 257 }; |
253 | 258 |
254 #endif // BASE_ID_MAP_H_ | 259 #endif // BASE_ID_MAP_H_ |
OLD | NEW |