diff --git a/parallel_hashmap/phmap.h b/parallel_hashmap/phmap.h index c725f87..ce43800 100644 --- a/parallel_hashmap/phmap.h +++ b/parallel_hashmap/phmap.h @@ -1628,20 +1628,22 @@ public: // called heterogeneous key support. template iterator find(const key_arg& key, size_t hashval) { - auto seq = probe(hashval); - while (true) { - Group g{ctrl_ + seq.offset()}; - for (int i : g.Match((h2_t)H2(hashval))) { - if (PHMAP_PREDICT_TRUE(PolicyTraits::apply( - EqualElement{key, eq_ref()}, - PolicyTraits::element(slots_ + seq.offset((size_t)i))))) - return iterator_at(seq.offset((size_t)i)); - } - if (PHMAP_PREDICT_TRUE(g.MatchEmpty())) - return end(); - seq.next(); - } + size_t offset; + if (find_impl(key, hashval, offset)) + return iterator_at(offset); + else + return end(); } + + template + pointer find_ptr(const key_arg& key, size_t hashval) { + size_t offset; + if (find_impl(key, hashval, offset)) + return &PolicyTraits::element(slots_ + offset); + else + return nullptr; + } + template iterator find(const key_arg& key) { return find(key, this->hash(key)); @@ -1722,6 +1724,24 @@ private: template friend struct phmap::priv::hashtable_debug_internal::HashtableDebugAccess; + template + bool find_impl(const key_arg& key, size_t hashval, size_t& offset) { + auto seq = probe(hashval); + while (true) { + Group g{ ctrl_ + seq.offset() }; + for (int i : g.Match((h2_t)H2(hashval))) { + offset = seq.offset((size_t)i); + if (PHMAP_PREDICT_TRUE(PolicyTraits::apply( + EqualElement{key, eq_ref()}, + PolicyTraits::element(slots_ + offset)))) + return true; + } + if (PHMAP_PREDICT_TRUE(g.MatchEmpty())) + return false; + seq.next(); + } + } + struct FindElement { template @@ -3376,18 +3396,20 @@ private: protected: template - std::pair find_as_pair(const key_arg& key, size_t hashval, L& mutexlock) + pointer find_ptr(const key_arg& key, size_t hashval, L& mutexlock) { Inner& inner = sets_[subidx(hashval)]; auto& set = inner.set_; mutexlock = std::move(L(inner)); - return std::make_pair(&inner, set.find(key, hashval)); + return set.find_ptr(key, hashval); } template iterator find(const key_arg& key, size_t hashval, L& mutexlock) { - auto res = find_as_pair(key, hashval, mutexlock); - return make_iterator(res.first, res.second); + Inner& inner = sets_[subidx(hashval)]; + auto& set = inner.set_; + mutexlock = std::move(L(inner)); + return make_iterator(&inner, set.find(key, hashval)); } template @@ -3690,10 +3712,10 @@ private: static_assert(std::is_invocable::value); #endif L m; - auto res = this->template find_as_pair(key, this->hash(key), m); - if (res.second == res.first->set_.end()) + auto ptr = this->template find_ptr(key, this->hash(key), m); + if (ptr == nullptr) return false; - std::forward(f)(Policy::value(&*res.second)); + std::forward(f)(Policy::value(ptr)); return true; } @@ -3703,11 +3725,11 @@ private: static_assert(std::is_invocable::value); #endif L m; - auto res = this->template find_as_pair(key, this->hash(key), m); - if (res.second != res.first->set_.end() && - std::forward(f)(Policy::value(&*res.second))) + auto it = this->template find(key, this->hash(key), m); + if (it == this->end()) return false; + if (std::forward(f)(Policy::value(&*it))) { - res.first->set_.erase(res.second); + this->erase(it); return true; } return false;