Chromium Code Reviews| 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 |