Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: base/containers/small_map.h

Issue 2830093003: Replace uses of hash_map in //base (Closed)
Patch Set: WebKit callers Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/containers/small_map_unittest.cc » ('j') | base/files/file_path.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #ifndef BASE_CONTAINERS_SMALL_MAP_H_ 5 #ifndef BASE_CONTAINERS_SMALL_MAP_H_
6 #define BASE_CONTAINERS_SMALL_MAP_H_ 6 #define BASE_CONTAINERS_SMALL_MAP_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <map> 10 #include <map>
11 #include <string> 11 #include <string>
12 #include <utility> 12 #include <utility>
13 13
14 #include "base/containers/hash_tables.h"
15 #include "base/logging.h" 14 #include "base/logging.h"
16 #include "base/memory/manual_constructor.h" 15 #include "base/memory/manual_constructor.h"
17 16
18 namespace base { 17 namespace base {
19 18
20 // An STL-like associative container which starts out backed by a simple 19 // An STL-like associative container which starts out backed by a simple
21 // array but switches to some other container type if it grows beyond a 20 // array but switches to some other container type if it grows beyond a
22 // fixed size. 21 // fixed size.
23 // 22 //
24 // WHAT TYPE OF MAP SHOULD YOU USE? 23 // WHAT TYPE OF MAP SHOULD YOU USE?
(...skipping 15 matching lines...) Expand all
40 // - base::small_map combines the performance benefits of the 39 // - base::small_map combines the performance benefits of the
41 // brute-force-searched vector for small cases (no extra heap allocations), 40 // brute-force-searched vector for small cases (no extra heap allocations),
42 // but can efficiently fall back if you end up adding many items. It will 41 // but can efficiently fall back if you end up adding many items. It will
43 // generate more code than std::map (at least 160 bytes for operator[]) 42 // generate more code than std::map (at least 160 bytes for operator[])
44 // which is bad if you have a "weird" key where map functions can't be 43 // which is bad if you have a "weird" key where map functions can't be
45 // duplicate-code-eliminated. If you have a one-off key and aren't in 44 // duplicate-code-eliminated. If you have a one-off key and aren't in
46 // performance-critical code, this bloat may negate some of the benefits and 45 // performance-critical code, this bloat may negate some of the benefits and
47 // you should consider on of the other options. 46 // you should consider on of the other options.
48 // 47 //
49 // base::small_map will pick up the comparator from the underlying map type. In 48 // base::small_map will pick up the comparator from the underlying map type. In
50 // std::map (and in MSVC additionally hash_map) only a "less" operator is 49 // std::map a "less" operator is defined, which requires us to do two
51 // defined, which requires us to do two comparisons per element when doing the 50 // comparisons per element when doing the brute-force search in the simple
52 // brute-force search in the simple array. 51 // array.
53 // 52 //
54 // We define default overrides for the common map types to avoid this 53 // We define default overrides for the common map types to avoid this
55 // double-compare, but you should be aware of this if you use your own 54 // double-compare, but you should be aware of this if you use your own
56 // operator< for your map and supply yor own version of == to the small_map. 55 // operator< for your map and supply yor own version of == to the small_map.
57 // You can use regular operator== by just doing: 56 // You can use regular operator== by just doing:
58 // 57 //
59 // base::small_map<std::map<MyKey, MyValue>, 4, std::equal_to<KyKey>> 58 // base::small_map<std::map<MyKey, MyValue>, 4, std::equal_to<KyKey>>
60 // 59 //
61 // 60 //
62 // USAGE 61 // USAGE
63 // ----- 62 // -----
64 // 63 //
65 // NormalMap: The map type to fall back to. This also defines the key 64 // NormalMap: The map type to fall back to. This also defines the key
66 // and value types for the small_map. 65 // and value types for the small_map.
67 // kArraySize: The size of the initial array of results. This will be 66 // kArraySize: The size of the initial array of results. This will be
68 // allocated with the small_map object rather than separately on 67 // allocated with the small_map object rather than separately on
69 // the heap. Once the map grows beyond this size, the map type 68 // the heap. Once the map grows beyond this size, the map type
70 // will be used instead. 69 // will be used instead.
71 // EqualKey: A functor which tests two keys for equality. If the wrapped 70 // EqualKey: A functor which tests two keys for equality. If the wrapped
72 // map type has a "key_equal" member (hash_map does), then that will 71 // map type has a "key_equal" member (unordered_map does), then that
73 // be used by default. If the wrapped map type has a strict weak 72 // will be used by default. If the wrapped map type has a strict
74 // ordering "key_compare" (std::map does), that will be used to 73 // weak ordering "key_compare" (std::map does), that will be used to
75 // implement equality by default. 74 // implement equality by default.
76 // MapInit: A functor that takes a ManualConstructor<NormalMap>* and uses it to 75 // MapInit: A functor that takes a ManualConstructor<NormalMap>* and uses it to
77 // initialize the map. This functor will be called at most once per 76 // initialize the map. This functor will be called at most once per
78 // small_map, when the map exceeds the threshold of kArraySize and we 77 // small_map, when the map exceeds the threshold of kArraySize and we
79 // are about to copy values from the array to the map. The functor 78 // are about to copy values from the array to the map. The functor
80 // *must* call one of the Init() methods provided by 79 // *must* call one of the Init() methods provided by
81 // ManualConstructor, since after it runs we assume that the NormalMap 80 // ManualConstructor, since after it runs we assume that the NormalMap
82 // has been initialized. 81 // has been initialized.
83 // 82 //
84 // example: 83 // example:
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 const typename M::key_type& right) { 134 const typename M::key_type& right) {
136 // Implements equality in terms of a strict weak ordering comparator. 135 // Implements equality in terms of a strict weak ordering comparator.
137 typename M::key_compare comp; 136 typename M::key_compare comp;
138 return !comp(left, right) && !comp(right, left); 137 return !comp(left, right) && !comp(right, left);
139 } 138 }
140 }; 139 };
141 }; 140 };
142 141
143 // Provide overrides to use operator== for key compare for the "normal" map and 142 // Provide overrides to use operator== for key compare for the "normal" map and
144 // hash map types. If you override the default comparator or allocator for a 143 // hash map types. If you override the default comparator or allocator for a
145 // map or hash_map, or use another type of map, this won't get used. 144 // map or unordered_map, or use another type of map, this won't get used.
146 //
147 // If we switch to using std::unordered_map for base::hash_map, then the
148 // hash_map specialization can be removed.
149 template <typename KeyType, typename ValueType> 145 template <typename KeyType, typename ValueType>
150 struct select_equal_key< std::map<KeyType, ValueType>, false> { 146 struct select_equal_key<std::map<KeyType, ValueType>, false> {
151 struct equal_key { 147 struct equal_key {
152 bool operator()(const KeyType& left, const KeyType& right) { 148 bool operator()(const KeyType& left, const KeyType& right) {
153 return left == right; 149 return left == right;
154 }
155 };
156 };
157 template <typename KeyType, typename ValueType>
158 struct select_equal_key< base::hash_map<KeyType, ValueType>, false> {
159 struct equal_key {
160 bool operator()(const KeyType& left, const KeyType& right) {
161 return left == right;
162 } 150 }
163 }; 151 };
164 }; 152 };
165 153
166 // Partial template specialization handles case where M::key_equal exists, e.g., 154 // Partial template specialization handles case where M::key_equal exists, e.g.,
167 // hash_map<>. 155 // unordered_map<>.
168 template <typename M> 156 template <typename M>
169 struct select_equal_key<M, true> { 157 struct select_equal_key<M, true> {
170 typedef typename M::key_equal equal_key; 158 typedef typename M::key_equal equal_key;
171 }; 159 };
172 160
173 } // namespace internal 161 } // namespace internal
174 162
175 template <typename NormalMap, 163 template <typename NormalMap,
176 int kArraySize = 4, 164 int kArraySize = 4,
177 typename EqualKey = typename internal::select_equal_key< 165 typename EqualKey = typename internal::select_equal_key<
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 inline NormalMap* map() { 543 inline NormalMap* map() {
556 CHECK(UsingFullMap()); 544 CHECK(UsingFullMap());
557 return map_.get(); 545 return map_.get();
558 } 546 }
559 inline const NormalMap* map() const { 547 inline const NormalMap* map() const {
560 CHECK(UsingFullMap()); 548 CHECK(UsingFullMap());
561 return map_.get(); 549 return map_.get();
562 } 550 }
563 551
564 private: 552 private:
565 int size_; // negative = using hash_map 553 int size_; // negative = using map
Łukasz Anforowicz 2017/04/24 18:46:10 nit: s/using map/using |map_| instead of |array_|.
566 554
567 MapInit functor_; 555 MapInit functor_;
568 556
569 // We want to call constructors and destructors manually, but we don't 557 // We want to call constructors and destructors manually, but we don't
570 // want to allocate and deallocate the memory used for them separately. 558 // want to allocate and deallocate the memory used for them separately.
571 // So, we use this crazy ManualConstructor class. Since C++11 it's possible 559 // So, we use this crazy ManualConstructor class. Since C++11 it's possible
572 // to use objects in unions like this, but the ManualDestructor syntax is 560 // to use objects in unions like this, but the ManualDestructor syntax is
573 // a bit better and doesn't have limitations on object type. 561 // a bit better and doesn't have limitations on object type.
574 // 562 //
575 // Since array_ and map_ are mutually exclusive, we'll put them in a 563 // Since array_ and map_ are mutually exclusive, we'll put them in a
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 typename EqualKey, 624 typename EqualKey,
637 typename Functor> 625 typename Functor>
638 inline bool small_map<NormalMap, kArraySize, EqualKey, Functor>::iterator:: 626 inline bool small_map<NormalMap, kArraySize, EqualKey, Functor>::iterator::
639 operator!=(const const_iterator& other) const { 627 operator!=(const const_iterator& other) const {
640 return other != *this; 628 return other != *this;
641 } 629 }
642 630
643 } // namespace base 631 } // namespace base
644 632
645 #endif // BASE_CONTAINERS_SMALL_MAP_H_ 633 #endif // BASE_CONTAINERS_SMALL_MAP_H_
OLDNEW
« no previous file with comments | « no previous file | base/containers/small_map_unittest.cc » ('j') | base/files/file_path.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698