diff --git a/parallel_hashmap/phmap.h b/parallel_hashmap/phmap.h index f897e28..e37774b 100644 --- a/parallel_hashmap/phmap.h +++ b/parallel_hashmap/phmap.h @@ -3376,12 +3376,18 @@ private: protected: template - iterator find(const key_arg& key, size_t hashval, L &mutexlock) { + std::pair find_as_pair(const key_arg& key, size_t hashval, L& mutexlock) + { Inner& inner = sets_[subidx(hashval)]; - auto& set = inner.set_; + auto& set = inner.set_; mutexlock = std::move(L(inner)); - auto it = set.find(key, hashval); - return make_iterator(&inner, it); + return std::make_pair(&inner, set.find(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); } template @@ -3603,7 +3609,7 @@ public: template iterator try_emplace_with_hash(size_t hashval, const_iterator, const key_arg& k, Args&&... args) { return try_emplace_with_hash(hashval, k, std::forward(args)...).first; - } + } // if map contains key, lambda is called with the mapped value (under read lock protection), // and if_contains returns true. This is a const API and lambda should not modify the value @@ -3614,6 +3620,15 @@ public: modify_if_impl(key, std::forward(f)); } + // if map contains key, lambda is called with the mapped value without read lock protection, + // and if_contains_unsafe returns true. This is a const API and lambda should not modify the value + // ----------------------------------------------------------------------------------------- + template + bool if_contains_unsafe(const key_arg& key, F&& f) const { + return const_cast(this)->template + modify_if_impl::DoNothing>(key, std::forward(f)); + } + // if map contains key, lambda is called with the mapped value (under write lock protection), // and modify_if returns true. This is a non-const API and lambda is allowed to modify the mapped value // ---------------------------------------------------------------------------------------------------- @@ -3674,10 +3689,10 @@ private: static_assert(std::is_invocable::value); #endif L m; - auto it = this->template find(key, this->hash(key), m); - if (it == this->end()) + auto res = this->template find_as_pair(key, this->hash(key), m); + if (res.second == res.first->set_.end()) return false; - std::forward(f)(Policy::value(&*it)); + std::forward(f)(Policy::value(&*res.second)); return true; }