OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project 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 // The reason we write our own hash map instead of using unordered_map in STL, | 5 // The reason we write our own hash map instead of using unordered_map in STL, |
6 // is that STL containers use a mutex pool on debug build, which will lead to | 6 // is that STL containers use a mutex pool on debug build, which will lead to |
7 // deadlock when we are using async signal handler. | 7 // deadlock when we are using async signal handler. |
8 | 8 |
9 #ifndef V8_BASE_HASHMAP_H_ | 9 #ifndef V8_BASE_HASHMAP_H_ |
10 #define V8_BASE_HASHMAP_H_ | 10 #define V8_BASE_HASHMAP_H_ |
11 | 11 |
12 #include <stdlib.h> | 12 #include <stdlib.h> |
13 | 13 |
14 #include "src/base/bits.h" | 14 #include "src/base/bits.h" |
15 #include "src/base/hashmap-entry.h" | 15 #include "src/base/hashmap-entry.h" |
16 #include "src/base/logging.h" | 16 #include "src/base/logging.h" |
17 | 17 |
18 namespace v8 { | 18 namespace v8 { |
19 namespace base { | 19 namespace base { |
20 | 20 |
21 class DefaultAllocationPolicy { | 21 class DefaultAllocationPolicy { |
22 public: | 22 public: |
23 V8_INLINE void* New(size_t size) { return malloc(size); } | 23 V8_INLINE void* New(size_t size) { return malloc(size); } |
24 V8_INLINE static void Delete(void* p) { free(p); } | 24 V8_INLINE static void Delete(void* p) { free(p); } |
25 }; | 25 }; |
26 | 26 |
27 // Metaprogramming helper to allow pointer keys to be passed by value and | 27 template <typename Key, typename Value, class MatchFun, class AllocationPolicy> |
28 // non-pointer keys by const reference. | |
29 template <typename Key> | |
30 struct MatchFunHelper; | |
31 | |
32 template <typename Key, typename Value, class AllocationPolicy> | |
33 class TemplateHashMapImpl { | 28 class TemplateHashMapImpl { |
34 public: | 29 public: |
35 typedef typename MatchFunHelper<Key>::Fun MatchFun; | |
36 typedef TemplateHashMapEntry<Key, Value> Entry; | 30 typedef TemplateHashMapEntry<Key, Value> Entry; |
37 | 31 |
38 // The default capacity. This is used by the call sites which want | 32 // The default capacity. This is used by the call sites which want |
39 // to pass in a non-default AllocationPolicy but want to use the | 33 // to pass in a non-default AllocationPolicy but want to use the |
40 // default value of capacity specified by the implementation. | 34 // default value of capacity specified by the implementation. |
41 static const uint32_t kDefaultHashMapCapacity = 8; | 35 static const uint32_t kDefaultHashMapCapacity = 8; |
42 | 36 |
43 // initial_capacity is the size of the initial hash map; | 37 // initial_capacity is the size of the initial hash map; |
44 // it must be a power of 2 (and thus must not be 0). | 38 // it must be a power of 2 (and thus must not be 0). |
45 TemplateHashMapImpl(MatchFun match, | 39 TemplateHashMapImpl(MatchFun match = MatchFun(), |
46 uint32_t capacity = kDefaultHashMapCapacity, | 40 uint32_t capacity = kDefaultHashMapCapacity, |
47 AllocationPolicy allocator = AllocationPolicy()); | 41 AllocationPolicy allocator = AllocationPolicy()); |
48 | 42 |
49 ~TemplateHashMapImpl(); | 43 ~TemplateHashMapImpl(); |
50 | 44 |
51 // If an entry with matching key is found, returns that entry. | 45 // If an entry with matching key is found, returns that entry. |
52 // Otherwise, nullptr is returned. | 46 // Otherwise, nullptr is returned. |
53 Entry* Lookup(const Key& key, uint32_t hash) const; | 47 Entry* Lookup(const Key& key, uint32_t hash) const; |
54 | 48 |
55 // If an entry with matching key is found, returns that entry. | 49 // If an entry with matching key is found, returns that entry. |
(...skipping 23 matching lines...) Expand all Loading... | |
79 // | 73 // |
80 // for (Entry* p = map.Start(); p != nullptr; p = map.Next(p)) { | 74 // for (Entry* p = map.Start(); p != nullptr; p = map.Next(p)) { |
81 // ... | 75 // ... |
82 // } | 76 // } |
83 // | 77 // |
84 // If entries are inserted during iteration, the effect of | 78 // If entries are inserted during iteration, the effect of |
85 // calling Next() is undefined. | 79 // calling Next() is undefined. |
86 Entry* Start() const; | 80 Entry* Start() const; |
87 Entry* Next(Entry* entry) const; | 81 Entry* Next(Entry* entry) const; |
88 | 82 |
89 // Some match functions defined for convenience. | |
90 // TODO(leszeks): This isn't really matching pointers, so the name doesn't | |
91 // really make sense, but we should remove this entirely and template the map | |
92 // on the matching function. | |
93 static bool PointersMatch(typename MatchFunHelper<Key>::KeyRef key1, | |
94 typename MatchFunHelper<Key>::KeyRef key2) { | |
95 return key1 == key2; | |
96 } | |
97 | |
98 private: | 83 private: |
99 MatchFun match_; | |
100 Entry* map_; | 84 Entry* map_; |
101 uint32_t capacity_; | 85 uint32_t capacity_; |
102 uint32_t occupancy_; | 86 uint32_t occupancy_; |
87 MatchFun match_; | |
103 AllocationPolicy allocator_; | 88 AllocationPolicy allocator_; |
104 | 89 |
105 Entry* map_end() const { return map_ + capacity_; } | 90 Entry* map_end() const { return map_ + capacity_; } |
106 Entry* Probe(const Key& key, uint32_t hash) const; | 91 Entry* Probe(const Key& key, uint32_t hash) const; |
107 Entry* FillEmptyEntry(Entry* entry, const Key& key, const Value& value, | 92 Entry* FillEmptyEntry(Entry* entry, const Key& key, const Value& value, |
108 uint32_t hash); | 93 uint32_t hash); |
109 void Initialize(uint32_t capacity); | 94 void Initialize(uint32_t capacity); |
110 void Resize(); | 95 void Resize(); |
111 }; | 96 }; |
112 | 97 |
113 template <typename Key> | 98 template <typename Key, typename Value, typename MatchFun, |
114 struct MatchFunHelper { | 99 class AllocationPolicy> |
115 typedef const Key& KeyRef; | 100 TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>:: |
116 typedef bool (*Fun)(KeyRef key1, KeyRef key2); | 101 TemplateHashMapImpl(MatchFun match, uint32_t initial_capacity, |
117 }; | 102 AllocationPolicy allocator) |
118 | 103 : match_(match), allocator_(allocator) { |
119 template <typename Key> | |
120 struct MatchFunHelper<Key*> { | |
121 typedef Key* KeyRef; | |
122 typedef bool (*Fun)(KeyRef key1, KeyRef key2); | |
123 }; | |
124 | |
125 typedef TemplateHashMapImpl<void*, void*, DefaultAllocationPolicy> HashMap; | |
126 | |
127 template <typename Key, typename Value, class AllocationPolicy> | |
128 TemplateHashMapImpl<Key, Value, AllocationPolicy>::TemplateHashMapImpl( | |
129 MatchFun match, uint32_t initial_capacity, AllocationPolicy allocator) | |
130 : allocator_(allocator) { | |
131 match_ = match; | |
132 Initialize(initial_capacity); | 104 Initialize(initial_capacity); |
133 } | 105 } |
134 | 106 |
135 template <typename Key, typename Value, class AllocationPolicy> | 107 template <typename Key, typename Value, typename MatchFun, |
136 TemplateHashMapImpl<Key, Value, AllocationPolicy>::~TemplateHashMapImpl() { | 108 class AllocationPolicy> |
109 TemplateHashMapImpl<Key, Value, MatchFun, | |
110 AllocationPolicy>::~TemplateHashMapImpl() { | |
137 allocator_.Delete(map_); | 111 allocator_.Delete(map_); |
138 } | 112 } |
139 | 113 |
140 template <typename Key, typename Value, class AllocationPolicy> | 114 template <typename Key, typename Value, typename MatchFun, |
141 typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* | 115 class AllocationPolicy> |
142 TemplateHashMapImpl<Key, Value, AllocationPolicy>::Lookup(const Key& key, | 116 typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* |
143 uint32_t hash) const { | 117 TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Lookup( |
118 const Key& key, uint32_t hash) const { | |
144 Entry* entry = Probe(key, hash); | 119 Entry* entry = Probe(key, hash); |
145 return entry->exists() ? entry : nullptr; | 120 return entry->exists() ? entry : nullptr; |
146 } | 121 } |
147 | 122 |
148 template <typename Key, typename Value, class AllocationPolicy> | 123 template <typename Key, typename Value, typename MatchFun, |
149 typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* | 124 class AllocationPolicy> |
150 TemplateHashMapImpl<Key, Value, AllocationPolicy>::LookupOrInsert( | 125 typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* |
126 TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::LookupOrInsert( | |
151 const Key& key, uint32_t hash) { | 127 const Key& key, uint32_t hash) { |
152 // Find a matching entry. | 128 // Find a matching entry. |
153 Entry* entry = Probe(key, hash); | 129 Entry* entry = Probe(key, hash); |
154 if (entry->exists()) { | 130 if (entry->exists()) { |
155 return entry; | 131 return entry; |
156 } | 132 } |
157 | 133 |
158 return FillEmptyEntry(entry, key, Value(), hash); | 134 return FillEmptyEntry(entry, key, Value(), hash); |
159 } | 135 } |
160 | 136 |
161 template <typename Key, typename Value, class AllocationPolicy> | 137 template <typename Key, typename Value, typename MatchFun, |
162 typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* | 138 class AllocationPolicy> |
163 TemplateHashMapImpl<Key, Value, AllocationPolicy>::InsertNew(const Key& key, | 139 typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* |
164 uint32_t hash) { | 140 TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::InsertNew( |
141 const Key& key, uint32_t hash) { | |
165 Entry* entry = Probe(key, hash); | 142 Entry* entry = Probe(key, hash); |
166 return FillEmptyEntry(entry, key, Value(), hash); | 143 return FillEmptyEntry(entry, key, Value(), hash); |
167 } | 144 } |
168 | 145 |
169 template <typename Key, typename Value, class AllocationPolicy> | 146 template <typename Key, typename Value, typename MatchFun, |
170 Value TemplateHashMapImpl<Key, Value, AllocationPolicy>::Remove(const Key& key, | 147 class AllocationPolicy> |
171 uint32_t hash) { | 148 Value TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Remove( |
149 const Key& key, uint32_t hash) { | |
172 // Lookup the entry for the key to remove. | 150 // Lookup the entry for the key to remove. |
173 Entry* p = Probe(key, hash); | 151 Entry* p = Probe(key, hash); |
174 if (!p->exists()) { | 152 if (!p->exists()) { |
175 // Key not found nothing to remove. | 153 // Key not found nothing to remove. |
176 return nullptr; | 154 return nullptr; |
177 } | 155 } |
178 | 156 |
179 Value value = p->value; | 157 Value value = p->value; |
180 // To remove an entry we need to ensure that it does not create an empty | 158 // To remove an entry we need to ensure that it does not create an empty |
181 // entry that will cause the search for another entry to stop too soon. If all | 159 // entry that will cause the search for another entry to stop too soon. If all |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
220 p = q; | 198 p = q; |
221 } | 199 } |
222 } | 200 } |
223 | 201 |
224 // Clear the entry which is allowed to en emptied. | 202 // Clear the entry which is allowed to en emptied. |
225 p->clear(); | 203 p->clear(); |
226 occupancy_--; | 204 occupancy_--; |
227 return value; | 205 return value; |
228 } | 206 } |
229 | 207 |
230 template <typename Key, typename Value, class AllocationPolicy> | 208 template <typename Key, typename Value, typename MatchFun, |
231 void TemplateHashMapImpl<Key, Value, AllocationPolicy>::Clear() { | 209 class AllocationPolicy> |
210 void TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Clear() { | |
232 // Mark all entries as empty. | 211 // Mark all entries as empty. |
233 const Entry* end = map_end(); | 212 const Entry* end = map_end(); |
234 for (Entry* entry = map_; entry < end; entry++) { | 213 for (Entry* entry = map_; entry < end; entry++) { |
235 entry->clear(); | 214 entry->clear(); |
236 } | 215 } |
237 occupancy_ = 0; | 216 occupancy_ = 0; |
238 } | 217 } |
239 | 218 |
240 template <typename Key, typename Value, class AllocationPolicy> | 219 template <typename Key, typename Value, typename MatchFun, |
241 typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* | 220 class AllocationPolicy> |
242 TemplateHashMapImpl<Key, Value, AllocationPolicy>::Start() const { | 221 typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* |
222 TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Start() const { | |
243 return Next(map_ - 1); | 223 return Next(map_ - 1); |
244 } | 224 } |
245 | 225 |
246 template <typename Key, typename Value, class AllocationPolicy> | 226 template <typename Key, typename Value, typename MatchFun, |
247 typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* | 227 class AllocationPolicy> |
248 TemplateHashMapImpl<Key, Value, AllocationPolicy>::Next(Entry* entry) const { | 228 typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* |
229 TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Next( | |
230 Entry* entry) const { | |
249 const Entry* end = map_end(); | 231 const Entry* end = map_end(); |
250 DCHECK(map_ - 1 <= entry && entry < end); | 232 DCHECK(map_ - 1 <= entry && entry < end); |
251 for (entry++; entry < end; entry++) { | 233 for (entry++; entry < end; entry++) { |
252 if (entry->exists()) { | 234 if (entry->exists()) { |
253 return entry; | 235 return entry; |
254 } | 236 } |
255 } | 237 } |
256 return nullptr; | 238 return nullptr; |
257 } | 239 } |
258 | 240 |
259 template <typename Key, typename Value, class AllocationPolicy> | 241 template <typename Key, typename Value, typename MatchFun, |
260 typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* | 242 class AllocationPolicy> |
261 TemplateHashMapImpl<Key, Value, AllocationPolicy>::Probe(const Key& key, | 243 typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* |
262 uint32_t hash) const { | 244 TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Probe( |
245 const Key& key, uint32_t hash) const { | |
263 DCHECK(base::bits::IsPowerOfTwo32(capacity_)); | 246 DCHECK(base::bits::IsPowerOfTwo32(capacity_)); |
264 Entry* entry = map_ + (hash & (capacity_ - 1)); | 247 Entry* entry = map_ + (hash & (capacity_ - 1)); |
265 const Entry* end = map_end(); | 248 const Entry* end = map_end(); |
266 DCHECK(map_ <= entry && entry < end); | 249 DCHECK(map_ <= entry && entry < end); |
267 | 250 |
268 DCHECK(occupancy_ < capacity_); // Guarantees loop termination. | 251 DCHECK(occupancy_ < capacity_); // Guarantees loop termination. |
269 while (entry->exists() && (hash != entry->hash || !match_(key, entry->key))) { | 252 while (entry->exists() && (hash != entry->hash || !match_(key, entry->key))) { |
270 entry++; | 253 entry++; |
271 if (entry >= end) { | 254 if (entry >= end) { |
272 entry = map_; | 255 entry = map_; |
273 } | 256 } |
274 } | 257 } |
275 | 258 |
276 return entry; | 259 return entry; |
277 } | 260 } |
278 | 261 |
279 template <typename Key, typename Value, class AllocationPolicy> | 262 template <typename Key, typename Value, typename MatchFun, |
280 typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* | 263 class AllocationPolicy> |
281 TemplateHashMapImpl<Key, Value, AllocationPolicy>::FillEmptyEntry( | 264 typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* |
265 TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::FillEmptyEntry( | |
282 Entry* entry, const Key& key, const Value& value, uint32_t hash) { | 266 Entry* entry, const Key& key, const Value& value, uint32_t hash) { |
283 DCHECK(!entry->exists()); | 267 DCHECK(!entry->exists()); |
284 | 268 |
285 new (entry) Entry(key, value, hash); | 269 new (entry) Entry(key, value, hash); |
286 occupancy_++; | 270 occupancy_++; |
287 | 271 |
288 // Grow the map if we reached >= 80% occupancy. | 272 // Grow the map if we reached >= 80% occupancy. |
289 if (occupancy_ + occupancy_ / 4 >= capacity_) { | 273 if (occupancy_ + occupancy_ / 4 >= capacity_) { |
290 Resize(); | 274 Resize(); |
291 entry = Probe(key, hash); | 275 entry = Probe(key, hash); |
292 } | 276 } |
293 | 277 |
294 return entry; | 278 return entry; |
295 } | 279 } |
296 | 280 |
297 template <typename Key, typename Value, class AllocationPolicy> | 281 template <typename Key, typename Value, typename MatchFun, |
298 void TemplateHashMapImpl<Key, Value, AllocationPolicy>::Initialize( | 282 class AllocationPolicy> |
283 void TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Initialize( | |
299 uint32_t capacity) { | 284 uint32_t capacity) { |
300 DCHECK(base::bits::IsPowerOfTwo32(capacity)); | 285 DCHECK(base::bits::IsPowerOfTwo32(capacity)); |
301 map_ = reinterpret_cast<Entry*>(allocator_.New(capacity * sizeof(Entry))); | 286 map_ = reinterpret_cast<Entry*>(allocator_.New(capacity * sizeof(Entry))); |
302 if (map_ == nullptr) { | 287 if (map_ == nullptr) { |
303 FATAL("Out of memory: HashMap::Initialize"); | 288 FATAL("Out of memory: HashMap::Initialize"); |
304 return; | 289 return; |
305 } | 290 } |
306 capacity_ = capacity; | 291 capacity_ = capacity; |
307 Clear(); | 292 Clear(); |
308 } | 293 } |
309 | 294 |
310 template <typename Key, typename Value, class AllocationPolicy> | 295 template <typename Key, typename Value, typename MatchFun, |
311 void TemplateHashMapImpl<Key, Value, AllocationPolicy>::Resize() { | 296 class AllocationPolicy> |
297 void TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Resize() { | |
312 Entry* map = map_; | 298 Entry* map = map_; |
313 uint32_t n = occupancy_; | 299 uint32_t n = occupancy_; |
314 | 300 |
315 // Allocate larger map. | 301 // Allocate larger map. |
316 Initialize(capacity_ * 2); | 302 Initialize(capacity_ * 2); |
317 | 303 |
318 // Rehash all current entries. | 304 // Rehash all current entries. |
319 for (Entry* entry = map; n > 0; entry++) { | 305 for (Entry* entry = map; n > 0; entry++) { |
320 if (entry->exists()) { | 306 if (entry->exists()) { |
321 Entry* new_entry = Probe(entry->key, entry->hash); | 307 Entry* new_entry = Probe(entry->key, entry->hash); |
322 new_entry = | 308 new_entry = |
323 FillEmptyEntry(new_entry, entry->key, entry->value, entry->hash); | 309 FillEmptyEntry(new_entry, entry->key, entry->value, entry->hash); |
324 n--; | 310 n--; |
325 } | 311 } |
326 } | 312 } |
327 | 313 |
328 // Delete old map. | 314 // Delete old map. |
329 allocator_.Delete(map); | 315 allocator_.Delete(map); |
330 } | 316 } |
331 | 317 |
318 template <typename AllocationPolicy> | |
319 class PointerTemplateHashMapImpl | |
320 : public TemplateHashMapImpl<void*, void*, bool (*)(void*, void*), | |
321 AllocationPolicy> { | |
322 typedef TemplateHashMapImpl<void*, void*, bool (*)(void*, void*), | |
323 AllocationPolicy> | |
324 Base; | |
rmcilroy
2016/09/20 16:06:03
weird formating here - I guess this was git cl for
Leszek Swirski
2016/09/26 16:54:52
Not really, I could define the MatchFun typedef hi
| |
325 | |
326 public: | |
327 typedef bool (*MatchFun)(void*, void*); | |
328 | |
329 PointerTemplateHashMapImpl(MatchFun match = PointersMatch, | |
330 uint32_t capacity = Base::kDefaultHashMapCapacity, | |
331 AllocationPolicy allocator = AllocationPolicy()) | |
332 : Base(match, capacity, allocator) {} | |
333 | |
334 static bool PointersMatch(void* key1, void* key2) { return key1 == key2; } | |
335 }; | |
336 | |
337 typedef PointerTemplateHashMapImpl<DefaultAllocationPolicy> HashMap; | |
338 | |
332 // A hash map for pointer keys and values with an STL-like interface. | 339 // A hash map for pointer keys and values with an STL-like interface. |
333 template <class Key, class Value, class AllocationPolicy> | 340 template <class Key, class Value, class AllocationPolicy> |
334 class TemplateHashMap | 341 class TemplateHashMap : private PointerTemplateHashMapImpl<AllocationPolicy> { |
335 : private TemplateHashMapImpl<void*, void*, AllocationPolicy> { | 342 typedef PointerTemplateHashMapImpl<AllocationPolicy> Base; |
343 | |
336 public: | 344 public: |
345 typedef bool (*MatchFun)(void*, void*); | |
346 | |
337 STATIC_ASSERT(sizeof(Key*) == sizeof(void*)); // NOLINT | 347 STATIC_ASSERT(sizeof(Key*) == sizeof(void*)); // NOLINT |
338 STATIC_ASSERT(sizeof(Value*) == sizeof(void*)); // NOLINT | 348 STATIC_ASSERT(sizeof(Value*) == sizeof(void*)); // NOLINT |
339 struct value_type { | 349 struct value_type { |
340 Key* first; | 350 Key* first; |
341 Value* second; | 351 Value* second; |
342 }; | 352 }; |
343 | 353 |
344 class Iterator { | 354 class Iterator { |
345 public: | 355 public: |
346 Iterator& operator++() { | 356 Iterator& operator++() { |
347 entry_ = map_->Next(entry_); | 357 entry_ = map_->Next(entry_); |
348 return *this; | 358 return *this; |
349 } | 359 } |
350 | 360 |
351 value_type* operator->() { return reinterpret_cast<value_type*>(entry_); } | 361 value_type* operator->() { return reinterpret_cast<value_type*>(entry_); } |
352 bool operator!=(const Iterator& other) { return entry_ != other.entry_; } | 362 bool operator!=(const Iterator& other) { return entry_ != other.entry_; } |
353 | 363 |
354 private: | 364 private: |
355 Iterator(const TemplateHashMapImpl<void*, void*, AllocationPolicy>* map, | 365 Iterator(const Base* map, typename Base::Entry* entry) |
356 typename TemplateHashMapImpl<void*, void*, | |
357 AllocationPolicy>::Entry* entry) | |
358 : map_(map), entry_(entry) {} | 366 : map_(map), entry_(entry) {} |
359 | 367 |
360 const TemplateHashMapImpl<void*, void*, AllocationPolicy>* map_; | 368 const Base* map_; |
361 typename TemplateHashMapImpl<void*, void*, AllocationPolicy>::Entry* entry_; | 369 typename Base::Entry* entry_; |
362 | 370 |
363 friend class TemplateHashMap; | 371 friend class TemplateHashMap; |
364 }; | 372 }; |
365 | 373 |
366 TemplateHashMap(typename TemplateHashMapImpl< | 374 TemplateHashMap(MatchFun match, |
367 void*, void*, AllocationPolicy>::MatchFun match, | |
368 AllocationPolicy allocator = AllocationPolicy()) | 375 AllocationPolicy allocator = AllocationPolicy()) |
369 : TemplateHashMapImpl<void*, void*, AllocationPolicy>( | 376 : Base(match, Base::kDefaultHashMapCapacity, allocator) {} |
370 match, | |
371 TemplateHashMapImpl<void*, void*, | |
372 AllocationPolicy>::kDefaultHashMapCapacity, | |
373 allocator) {} | |
374 | 377 |
375 Iterator begin() const { return Iterator(this, this->Start()); } | 378 Iterator begin() const { return Iterator(this, this->Start()); } |
376 Iterator end() const { return Iterator(this, nullptr); } | 379 Iterator end() const { return Iterator(this, nullptr); } |
377 Iterator find(Key* key, bool insert = false) { | 380 Iterator find(Key* key, bool insert = false) { |
378 if (insert) { | 381 if (insert) { |
379 return Iterator(this, this->LookupOrInsert(key, key->Hash())); | 382 return Iterator(this, this->LookupOrInsert(key, key->Hash())); |
380 } | 383 } |
381 return Iterator(this, this->Lookup(key, key->Hash())); | 384 return Iterator(this, this->Lookup(key, key->Hash())); |
382 } | 385 } |
383 }; | 386 }; |
384 | 387 |
385 } // namespace base | 388 } // namespace base |
386 } // namespace v8 | 389 } // namespace v8 |
387 | 390 |
388 #endif // V8_BASE_HASHMAP_H_ | 391 #endif // V8_BASE_HASHMAP_H_ |
OLD | NEW |