From 8bc5c5f6426d5118d55bcaf3525e16c8da703d78 Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 23 Oct 2020 21:57:54 -0400 Subject: [PATCH] add public hash() function, and contains() taking a precomputed hashval - issue #71 --- parallel_hashmap/phmap.h | 56 +++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/parallel_hashmap/phmap.h b/parallel_hashmap/phmap.h index 3034340..643f981 100644 --- a/parallel_hashmap/phmap.h +++ b/parallel_hashmap/phmap.h @@ -1616,7 +1616,7 @@ public: template void prefetch(const key_arg& key) const { - prefetch_hash(HashElement{hash_ref()}(key)); + prefetch_hash(this->hash(key)); } // The API of find() has two extensions. @@ -1644,7 +1644,7 @@ public: } template iterator find(const key_arg& key) { - return find(key, HashElement{hash_ref()}(key)); + return find(key, this->hash(key)); } template @@ -1653,7 +1653,7 @@ public: } template const_iterator find(const key_arg& key) const { - return find(key, HashElement{hash_ref()}(key)); + return find(key, this->hash(key)); } template @@ -1661,6 +1661,11 @@ public: return find(key) != end(); } + template + bool contains(const key_arg& key, size_t hash) const { + return find(key, hash) != end(); + } + template std::pair equal_range(const key_arg& key) { auto it = find(key); @@ -1708,6 +1713,11 @@ public: a.swap(b); } + template + size_t hash(const K& key) const { + return HashElement{hash_ref()}(key); + } + private: template friend struct phmap::priv::hashtable_debug_internal::HashtableDebugAccess; @@ -1756,8 +1766,7 @@ private: { template std::pair operator()(const K& key, Args&&... args) const { - return s.emplace_decomposable(key, typename raw_hash_set::HashElement{s.hash_ref()}(key), - std::forward(args)...); + return s.emplace_decomposable(key, s.hash(key), std::forward(args)...); } raw_hash_set& s; }; @@ -2041,7 +2050,7 @@ protected: template std::pair find_or_prepare_insert(const K& key) { - return find_or_prepare_insert(key, HashElement{hash_ref()}(key)); + return find_or_prepare_insert(key, this->hash(key)); } size_t prepare_insert(size_t hash) PHMAP_ATTRIBUTE_NOINLINE { @@ -2826,7 +2835,7 @@ public: if (!node) return {end(), false, node_type()}; auto& key = node.key(); - size_t hashval = HashElement{hash_ref()}(key); + size_t hashval = this->hash(key); Inner& inner = sets_[subidx(hashval)]; auto& set = inner.set_; @@ -2852,7 +2861,7 @@ public: template std::pair emplace_decomposable(const K& key, Args&&... args) { - size_t hashval = HashElement{hash_ref()}(key); + size_t hashval = this->hash(key); Inner& inner = sets_[subidx(hashval)]; auto& set = inner.set_; typename Lockable::UniqueLock m(inner); @@ -2898,7 +2907,7 @@ public: PolicyTraits::construct(&alloc_ref(), slot, std::forward(args)...); const auto& elem = PolicyTraits::element(slot); - size_t hashval = HashElement{hash_ref()}(PolicyTraits::key(slot)); + size_t hashval = this->hash(PolicyTraits::key(slot)); Inner& inner = sets_[subidx(hashval)]; auto& set = inner.set_; typename Lockable::UniqueLock m(inner); @@ -2927,7 +2936,7 @@ public: template iterator lazy_emplace(const key_arg& key, F&& f) { - auto hashval = HashElement{hash_ref()}(key); + auto hashval = this->hash(key); Inner& inner = sets_[subidx(hashval)]; auto& set = inner.set_; typename Lockable::UniqueLock m(inner); @@ -2960,7 +2969,7 @@ public: // -------------------------------------------------------------------- template size_type erase(const key_arg& key) { - auto hashval = HashElement{hash_ref()}(key); + auto hashval = this->hash(key); Inner& inner = sets_[subidx(hashval)]; auto& set = inner.set_; typename Lockable::UpgradeLock m(inner); @@ -3092,7 +3101,7 @@ public: template void prefetch(const key_arg& key) const { (void)key; - size_t hashval = HashElement{hash_ref()}(key); + size_t hashval = this->hash(key); const Inner& inner = sets_[subidx(hashval)]; const auto& set = inner.set_; typename Lockable::SharedLock m(const_cast(inner)); @@ -3115,7 +3124,7 @@ public: template iterator find(const key_arg& key) { - return find(key, HashElement{hash_ref()}(key)); + return find(key, this->hash(key)); } template @@ -3125,7 +3134,7 @@ public: template const_iterator find(const key_arg& key) const { - return find(key, HashElement{hash_ref()}(key)); + return find(key, this->hash(key)); } template @@ -3133,6 +3142,11 @@ public: return find(key) != end(); } + template + bool contains(const key_arg& key, size_t hashval) const { + return find(key, hashval) != end(); + } + template std::pair equal_range(const key_arg& key) { auto it = find(key); @@ -3185,6 +3199,11 @@ public: a.swap(b); } + template + size_t hash(const K& key) const { + return HashElement{hash_ref()}(key); + } + #ifndef PHMAP_NON_DETERMINISTIC template bool dump(OutputArchive& ar) const; @@ -3280,7 +3299,7 @@ protected: template std::tuple find_or_prepare_insert(const K& key, typename Lockable::UniqueLock &mutexlock) { - auto hashval = HashElement{hash_ref()}(key); + auto hashval = this->hash(key); Inner& inner = sets_[subidx(hashval)]; auto& set = inner.set_; mutexlock = std::move(typename Lockable::UniqueLock(inner)); @@ -3301,11 +3320,6 @@ protected: return ((hashval >> 8) ^ (hashval >> 16) ^ (hashval >> 24)) & mask; } - template - size_t hash(const K& key) const { - return HashElement{hash_ref()}(key); - } - static size_t subcnt() { return num_tables; } @@ -3991,7 +4005,7 @@ struct HashtableDebugAccess> static size_t GetNumProbes(const Set& set, const typename Set::key_type& key) { size_t num_probes = 0; - size_t hash = typename Set::HashElement{set.hash_ref()}(key); + size_t hash = set.hash(key); auto seq = set.probe(hash); while (true) { priv::Group g{set.ctrl_ + seq.offset()};