Merge pull request #95 from bpmckinnon/master

Add if_contains_unsafe function that does not lock the parallel hash …
This commit is contained in:
Gregory Popovitch
2021-05-08 07:47:33 -04:00
committed by GitHub
+26 -11
View File
@@ -3376,12 +3376,18 @@ private:
protected:
template <class K = key_type, class L = typename Lockable::SharedLock>
iterator find(const key_arg<K>& key, size_t hashval, L &mutexlock) {
std::pair<Inner*, EmbeddedIterator> find_as_pair(const key_arg<K>& key, size_t hashval, L& mutexlock)
{
Inner& inner = sets_[subidx(hashval)];
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 <class K = key_type, class L = typename Lockable::SharedLock>
iterator find(const key_arg<K>& key, size_t hashval, L& mutexlock) {
auto res = find_as_pair(key, hashval, mutexlock);
return make_iterator(res.first, res.second);
}
template <class K>
@@ -3614,6 +3620,16 @@ public:
modify_if_impl<K, F, typename Lockable::SharedLock>(key, std::forward<F>(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
// This should be used only if we know that no other thread may be mutating the map at the time.
// -----------------------------------------------------------------------------------------
template <class K = key_type, class F>
bool if_contains_unsafe(const key_arg<K>& key, F&& f) const {
return const_cast<parallel_hash_map*>(this)->template
modify_if_impl<K, F, LockableBaseImpl<phmap::NullMutex>::DoNothing>(key, std::forward<F>(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 +3690,10 @@ private:
static_assert(std::is_invocable<F, mapped_type&>::value);
#endif
L m;
auto it = this->template find<K, L>(key, this->hash(key), m);
if (it == this->end())
auto res = this->template find_as_pair<K, L>(key, this->hash(key), m);
if (res.second == res.first->set_.end())
return false;
std::forward<F>(f)(Policy::value(&*it));
std::forward<F>(f)(Policy::value(&*res.second));
return true;
}
@@ -3687,12 +3703,11 @@ private:
static_assert(std::is_invocable<F, mapped_type&>::value);
#endif
L m;
auto it = this->template find<K, L>(key, this->hash(key), m);
if (it == this->end())
return false;
if (std::forward<F>(f)(Policy::value(&*it)))
auto res = this->template find_as_pair<K, L>(key, this->hash(key), m);
if (res.second != res.first->set_.end() &&
std::forward<F>(f)(Policy::value(&*res.second)))
{
this->erase(it);
res.first->set_.erase(res.second);
return true;
}
return false;