| 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_ |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 | 41 |
| 42 ~TemplateHashMapImpl(); | 42 ~TemplateHashMapImpl(); |
| 43 | 43 |
| 44 // HashMap entries are (key, value, hash) triplets. | 44 // HashMap entries are (key, value, hash) triplets. |
| 45 // Some clients may not need to use the value slot | 45 // Some clients may not need to use the value slot |
| 46 // (e.g. implementers of sets, where the key is the value). | 46 // (e.g. implementers of sets, where the key is the value). |
| 47 struct Entry { | 47 struct Entry { |
| 48 void* key; | 48 void* key; |
| 49 void* value; | 49 void* value; |
| 50 uint32_t hash; // The full hash value for key | 50 uint32_t hash; // The full hash value for key |
| 51 int order; // If you never remove entries this is the insertion order. | |
| 52 }; | 51 }; |
| 53 | 52 |
| 54 // If an entry with matching key is found, returns that entry. | 53 // If an entry with matching key is found, returns that entry. |
| 55 // Otherwise, NULL is returned. | 54 // Otherwise, NULL is returned. |
| 56 Entry* Lookup(void* key, uint32_t hash) const; | 55 Entry* Lookup(void* key, uint32_t hash) const; |
| 57 | 56 |
| 58 // If an entry with matching key is found, returns that entry. | 57 // If an entry with matching key is found, returns that entry. |
| 59 // If no matching entry is found, a new entry is inserted with | 58 // If no matching entry is found, a new entry is inserted with |
| 60 // corresponding key, key hash, and NULL value. | 59 // corresponding key, key hash, and NULL value. |
| 61 Entry* LookupOrInsert(void* key, uint32_t hash, | 60 Entry* LookupOrInsert(void* key, uint32_t hash, |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 TemplateHashMapImpl<AllocationPolicy>::InsertNew(void* key, uint32_t hash, | 144 TemplateHashMapImpl<AllocationPolicy>::InsertNew(void* key, uint32_t hash, |
| 146 AllocationPolicy allocator) { | 145 AllocationPolicy allocator) { |
| 147 // Find a matching entry. | 146 // Find a matching entry. |
| 148 Entry* p = Probe(key, hash); | 147 Entry* p = Probe(key, hash); |
| 149 DCHECK(p->key == NULL); | 148 DCHECK(p->key == NULL); |
| 150 | 149 |
| 151 // No entry found; insert one. | 150 // No entry found; insert one. |
| 152 p->key = key; | 151 p->key = key; |
| 153 p->value = NULL; | 152 p->value = NULL; |
| 154 p->hash = hash; | 153 p->hash = hash; |
| 155 p->order = occupancy_; | |
| 156 occupancy_++; | 154 occupancy_++; |
| 157 | 155 |
| 158 // Grow the map if we reached >= 80% occupancy. | 156 // Grow the map if we reached >= 80% occupancy. |
| 159 if (occupancy_ + occupancy_ / 4 >= capacity_) { | 157 if (occupancy_ + occupancy_ / 4 >= capacity_) { |
| 160 Resize(allocator); | 158 Resize(allocator); |
| 161 p = Probe(key, hash); | 159 p = Probe(key, hash); |
| 162 } | 160 } |
| 163 | 161 |
| 164 return p; | 162 return p; |
| 165 } | 163 } |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 uint32_t n = occupancy_; | 291 uint32_t n = occupancy_; |
| 294 | 292 |
| 295 // Allocate larger map. | 293 // Allocate larger map. |
| 296 Initialize(capacity_ * 2, allocator); | 294 Initialize(capacity_ * 2, allocator); |
| 297 | 295 |
| 298 // Rehash all current entries. | 296 // Rehash all current entries. |
| 299 for (Entry* p = map; n > 0; p++) { | 297 for (Entry* p = map; n > 0; p++) { |
| 300 if (p->key != NULL) { | 298 if (p->key != NULL) { |
| 301 Entry* entry = LookupOrInsert(p->key, p->hash, allocator); | 299 Entry* entry = LookupOrInsert(p->key, p->hash, allocator); |
| 302 entry->value = p->value; | 300 entry->value = p->value; |
| 303 entry->order = p->order; | |
| 304 n--; | 301 n--; |
| 305 } | 302 } |
| 306 } | 303 } |
| 307 | 304 |
| 308 // Delete old map. | 305 // Delete old map. |
| 309 AllocationPolicy::Delete(map); | 306 AllocationPolicy::Delete(map); |
| 310 } | 307 } |
| 311 | 308 |
| 312 // A hash map for pointer keys and values with an STL-like interface. | 309 // A hash map for pointer keys and values with an STL-like interface. |
| 313 template <class Key, class Value, class AllocationPolicy> | 310 template <class Key, class Value, class AllocationPolicy> |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 return Iterator(this, this->LookupOrInsert(key, key->Hash(), allocator)); | 354 return Iterator(this, this->LookupOrInsert(key, key->Hash(), allocator)); |
| 358 } | 355 } |
| 359 return Iterator(this, this->Lookup(key, key->Hash())); | 356 return Iterator(this, this->Lookup(key, key->Hash())); |
| 360 } | 357 } |
| 361 }; | 358 }; |
| 362 | 359 |
| 363 } // namespace base | 360 } // namespace base |
| 364 } // namespace v8 | 361 } // namespace v8 |
| 365 | 362 |
| 366 #endif // V8_BASE_HASHMAP_H_ | 363 #endif // V8_BASE_HASHMAP_H_ |
| OLD | NEW |