Index: src/base/hashmap.h |
diff --git a/src/base/hashmap.h b/src/base/hashmap.h |
index 619108a0a78ed12660fe2325377da2dc952e984b..6bef83ed4d8c7cbb2d25c55625fd65ade6b58b00 100644 |
--- a/src/base/hashmap.h |
+++ b/src/base/hashmap.h |
@@ -84,7 +84,7 @@ class TemplateHashMapImpl { |
// If entries are inserted during iteration, the effect of |
// calling Next() is undefined. |
Entry* Start() const; |
- Entry* Next(Entry* p) const; |
+ Entry* Next(Entry* entry) const; |
// Some match functions defined for convenience. |
// TODO(leszeks): This isn't really matching pointers, so the name doesn't |
@@ -104,6 +104,8 @@ class TemplateHashMapImpl { |
Entry* map_end() const { return map_ + capacity_; } |
Entry* Probe(const Key& key, uint32_t hash) const; |
+ Entry* FillEmptyEntry(Entry* entry, const Key& key, const Value& value, |
+ uint32_t hash); |
void Initialize(uint32_t capacity); |
void Resize(); |
}; |
@@ -139,8 +141,8 @@ template <typename Key, typename Value, class AllocationPolicy> |
typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* |
TemplateHashMapImpl<Key, Value, AllocationPolicy>::Lookup(const Key& key, |
uint32_t hash) const { |
- Entry* p = Probe(key, hash); |
- return p->exists() ? p : nullptr; |
+ Entry* entry = Probe(key, hash); |
+ return entry->exists() ? entry : nullptr; |
} |
template <typename Key, typename Value, class AllocationPolicy> |
@@ -148,34 +150,20 @@ typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* |
TemplateHashMapImpl<Key, Value, AllocationPolicy>::LookupOrInsert( |
const Key& key, uint32_t hash) { |
// Find a matching entry. |
- Entry* p = Probe(key, hash); |
- if (p->exists()) { |
- return p; |
+ Entry* entry = Probe(key, hash); |
+ if (entry->exists()) { |
+ return entry; |
} |
- return InsertNew(key, hash); |
+ return FillEmptyEntry(entry, key, Value(), hash); |
} |
template <typename Key, typename Value, class AllocationPolicy> |
typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* |
TemplateHashMapImpl<Key, Value, AllocationPolicy>::InsertNew(const Key& key, |
uint32_t hash) { |
- // Find a matching entry. |
- Entry* p = Probe(key, hash); |
- DCHECK(!p->exists()); |
- |
- // No entry found; construct one in-place in the empty slot using placement |
- // new. |
- new (p) Entry(key, Value(), hash); |
- occupancy_++; |
- |
- // Grow the map if we reached >= 80% occupancy. |
- if (occupancy_ + occupancy_ / 4 >= capacity_) { |
- Resize(); |
- p = Probe(key, hash); |
- } |
- |
- return p; |
+ Entry* entry = Probe(key, hash); |
+ return FillEmptyEntry(entry, key, Value(), hash); |
} |
template <typename Key, typename Value, class AllocationPolicy> |
@@ -243,8 +231,8 @@ template <typename Key, typename Value, class AllocationPolicy> |
void TemplateHashMapImpl<Key, Value, AllocationPolicy>::Clear() { |
// Mark all entries as empty. |
const Entry* end = map_end(); |
- for (Entry* p = map_; p < end; p++) { |
- p->clear(); |
+ for (Entry* entry = map_; entry < end; entry++) { |
+ entry->clear(); |
} |
occupancy_ = 0; |
} |
@@ -257,12 +245,12 @@ TemplateHashMapImpl<Key, Value, AllocationPolicy>::Start() const { |
template <typename Key, typename Value, class AllocationPolicy> |
typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* |
-TemplateHashMapImpl<Key, Value, AllocationPolicy>::Next(Entry* p) const { |
+TemplateHashMapImpl<Key, Value, AllocationPolicy>::Next(Entry* entry) const { |
const Entry* end = map_end(); |
- DCHECK(map_ - 1 <= p && p < end); |
- for (p++; p < end; p++) { |
- if (p->exists()) { |
- return p; |
+ DCHECK(map_ - 1 <= entry && entry < end); |
+ for (entry++; entry < end; entry++) { |
+ if (entry->exists()) { |
+ return entry; |
} |
} |
return nullptr; |
@@ -273,19 +261,37 @@ typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* |
TemplateHashMapImpl<Key, Value, AllocationPolicy>::Probe(const Key& key, |
uint32_t hash) const { |
DCHECK(base::bits::IsPowerOfTwo32(capacity_)); |
- Entry* p = map_ + (hash & (capacity_ - 1)); |
+ Entry* entry = map_ + (hash & (capacity_ - 1)); |
const Entry* end = map_end(); |
- DCHECK(map_ <= p && p < end); |
+ DCHECK(map_ <= entry && entry < end); |
DCHECK(occupancy_ < capacity_); // Guarantees loop termination. |
- while (p->exists() && (hash != p->hash || !match_(key, p->key))) { |
- p++; |
- if (p >= end) { |
- p = map_; |
+ while (entry->exists() && (hash != entry->hash || !match_(key, entry->key))) { |
+ entry++; |
+ if (entry >= end) { |
+ entry = map_; |
} |
} |
- return p; |
+ return entry; |
+} |
+ |
+template <typename Key, typename Value, class AllocationPolicy> |
+typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* |
+TemplateHashMapImpl<Key, Value, AllocationPolicy>::FillEmptyEntry( |
+ Entry* entry, const Key& key, const Value& value, uint32_t hash) { |
+ DCHECK(!entry->exists()); |
+ |
+ new (entry) Entry(key, value, hash); |
+ occupancy_++; |
+ |
+ // Grow the map if we reached >= 80% occupancy. |
+ if (occupancy_ + occupancy_ / 4 >= capacity_) { |
+ Resize(); |
+ entry = Probe(key, hash); |
+ } |
+ |
+ return entry; |
} |
template <typename Key, typename Value, class AllocationPolicy> |
@@ -310,10 +316,11 @@ void TemplateHashMapImpl<Key, Value, AllocationPolicy>::Resize() { |
Initialize(capacity_ * 2); |
// Rehash all current entries. |
- for (Entry* p = map; n > 0; p++) { |
- if (p->exists()) { |
- Entry* entry = LookupOrInsert(p->key, p->hash); |
- entry->value = p->value; |
+ for (Entry* entry = map; n > 0; entry++) { |
+ if (entry->exists()) { |
+ Entry* new_entry = Probe(entry->key, entry->hash); |
+ new_entry = |
+ FillEmptyEntry(new_entry, entry->key, entry->value, entry->hash); |
n--; |
} |
} |