From 4468822524c34921f46eed4bac1f339af44d1084 Mon Sep 17 00:00:00 2001 From: Ed Catmur Date: Tue, 12 Sep 2023 00:31:30 +0100 Subject: [PATCH] Add try_emplace_p extension method Iterators are invalidated by concurrent insertion (rehash, resize, etc...) whereas for node-based containers, pointers are only invalidated by erase/clear. --- parallel_hashmap/phmap.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/parallel_hashmap/phmap.h b/parallel_hashmap/phmap.h index 0af75ea..ad76110 100644 --- a/parallel_hashmap/phmap.h +++ b/parallel_hashmap/phmap.h @@ -4022,6 +4022,24 @@ class parallel_hash_map : public parallel_hash_set(res); } + // returns {pointer, bool} instead of {iterator, bool} per try_emplace. + // useful for node-based containers, since the pointer is not invalidated by concurrent insert etc. + template + std::pair try_emplace_p(K&& k, Args&&... args) { + size_t hashval = this->hash(k); + typename Lockable::UniqueLock m; + auto res = this->find_or_prepare_insert_with_hash(hashval, k, m); + typename Base::Inner *inner = std::get<0>(res); + if (std::get<2>(res)) { + inner->set_.emplace_at(std::get<1>(res), std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)); + inner->set_.set_ctrl(std::get<1>(res), H2(hashval)); + } + auto it = this->iterator_at(inner, inner->set_.iterator_at(std::get<1>(res))); + return {&*it, std::get<2>(res)}; + } + // ----------- end of phmap extensions -------------------------- template