| Index: src/base/hashmap.h
|
| diff --git a/src/base/hashmap.h b/src/base/hashmap.h
|
| index d8151861cbe070457560602aab02768927d60b93..54038c5ef350d00423b0d36607e964b96b77a9bc 100644
|
| --- a/src/base/hashmap.h
|
| +++ b/src/base/hashmap.h
|
| @@ -269,7 +269,7 @@ TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Probe(
|
| DCHECK(map_ <= entry && entry < end);
|
|
|
| DCHECK(occupancy_ < capacity_); // Guarantees loop termination.
|
| - while (entry->exists() && (hash != entry->hash || !match_(key, entry->key))) {
|
| + while (entry->exists() && !match_(hash, entry->hash, key, entry->key)) {
|
| entry++;
|
| if (entry >= end) {
|
| entry = map_;
|
| @@ -337,12 +337,31 @@ void TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Resize(
|
| AllocationPolicy::Delete(map);
|
| }
|
|
|
| +// Match function which compares hashes before executing a (potentially
|
| +// expensive) key comparison.
|
| +template <typename Key, typename MatchFun>
|
| +struct HashEqualityThenKeyMatcher {
|
| + explicit HashEqualityThenKeyMatcher(MatchFun match) : match_(match) {}
|
| +
|
| + bool operator()(uint32_t hash1, uint32_t hash2, const Key& key1,
|
| + const Key& key2) const {
|
| + return hash1 == hash2 && match_(key1, key2);
|
| + }
|
| +
|
| + private:
|
| + MatchFun match_;
|
| +};
|
| +
|
| +// Hashmap<void*, void*> which takes a custom key comparison function pointer.
|
| template <typename AllocationPolicy>
|
| class CustomMatcherTemplateHashMapImpl
|
| - : public TemplateHashMapImpl<void*, void*, bool (*)(void*, void*),
|
| - AllocationPolicy> {
|
| - typedef TemplateHashMapImpl<void*, void*, bool (*)(void*, void*),
|
| - AllocationPolicy>
|
| + : public TemplateHashMapImpl<
|
| + void*, void*,
|
| + HashEqualityThenKeyMatcher<void*, bool (*)(void*, void*)>,
|
| + AllocationPolicy> {
|
| + typedef TemplateHashMapImpl<
|
| + void*, void*, HashEqualityThenKeyMatcher<void*, bool (*)(void*, void*)>,
|
| + AllocationPolicy>
|
| Base;
|
|
|
| public:
|
| @@ -351,24 +370,35 @@ class CustomMatcherTemplateHashMapImpl
|
| CustomMatcherTemplateHashMapImpl(
|
| MatchFun match, uint32_t capacity = Base::kDefaultHashMapCapacity,
|
| AllocationPolicy allocator = AllocationPolicy())
|
| - : Base(capacity, match, allocator) {}
|
| + : Base(capacity, HashEqualityThenKeyMatcher<void*, MatchFun>(match),
|
| + allocator) {}
|
| };
|
|
|
| typedef CustomMatcherTemplateHashMapImpl<DefaultAllocationPolicy>
|
| CustomMatcherHashMap;
|
|
|
| +// Match function which compares keys directly by equality.
|
| +template <typename Key>
|
| +struct KeyEqualityMatcher {
|
| + bool operator()(uint32_t hash1, uint32_t hash2, const Key& key1,
|
| + const Key& key2) const {
|
| + return key1 == key2;
|
| + }
|
| +};
|
| +
|
| +// Hashmap<void*, void*> which compares the key pointers directly.
|
| template <typename AllocationPolicy>
|
| class PointerTemplateHashMapImpl
|
| - : public TemplateHashMapImpl<void*, void*, std::equal_to<void*>,
|
| + : public TemplateHashMapImpl<void*, void*, KeyEqualityMatcher<void*>,
|
| AllocationPolicy> {
|
| - typedef TemplateHashMapImpl<void*, void*, std::equal_to<void*>,
|
| + typedef TemplateHashMapImpl<void*, void*, KeyEqualityMatcher<void*>,
|
| AllocationPolicy>
|
| Base;
|
|
|
| public:
|
| PointerTemplateHashMapImpl(uint32_t capacity = Base::kDefaultHashMapCapacity,
|
| AllocationPolicy allocator = AllocationPolicy())
|
| - : Base(capacity, std::equal_to<void*>(), allocator) {}
|
| + : Base(capacity, KeyEqualityMatcher<void*>(), allocator) {}
|
| };
|
|
|
| typedef PointerTemplateHashMapImpl<DefaultAllocationPolicy> HashMap;
|
| @@ -376,8 +406,13 @@ typedef PointerTemplateHashMapImpl<DefaultAllocationPolicy> HashMap;
|
| // A hash map for pointer keys and values with an STL-like interface.
|
| template <class Key, class Value, class MatchFun, class AllocationPolicy>
|
| class TemplateHashMap
|
| - : private TemplateHashMapImpl<void*, void*, MatchFun, AllocationPolicy> {
|
| - typedef TemplateHashMapImpl<void*, void*, MatchFun, AllocationPolicy> Base;
|
| + : private TemplateHashMapImpl<void*, void*,
|
| + HashEqualityThenKeyMatcher<void*, MatchFun>,
|
| + AllocationPolicy> {
|
| + typedef TemplateHashMapImpl<void*, void*,
|
| + HashEqualityThenKeyMatcher<void*, MatchFun>,
|
| + AllocationPolicy>
|
| + Base;
|
|
|
| public:
|
| STATIC_ASSERT(sizeof(Key*) == sizeof(void*)); // NOLINT
|
| @@ -409,7 +444,8 @@ class TemplateHashMap
|
|
|
| TemplateHashMap(MatchFun match,
|
| AllocationPolicy allocator = AllocationPolicy())
|
| - : Base(Base::kDefaultHashMapCapacity, match, allocator) {}
|
| + : Base(Base::kDefaultHashMapCapacity,
|
| + HashEqualityThenKeyMatcher<void*, MatchFun>(match), allocator) {}
|
|
|
| Iterator begin() const { return Iterator(this, this->Start()); }
|
| Iterator end() const { return Iterator(this, nullptr); }
|
|
|