From 0e723143fa87766ee944b69900b6a65e8bc88555 Mon Sep 17 00:00:00 2001 From: Brian McKinnon Date: Sat, 2 May 2020 16:47:33 -0500 Subject: [PATCH] Add "if_contains" to parallel_hash_map so the value does not need to be copied to be read in a thread-safe manner Add tests for parallel_hash_map thread-safe functions. --- parallel_hashmap/phmap.h | 10 +++++++++ tests/flat_hash_map_test.cc | 1 + tests/parallel_flat_hash_map_test.cc | 1 + tests/parallel_hash_map_test.cc | 32 ++++++++++++++++++++++++++++ tests/parallel_node_hash_map_test.cc | 1 + 5 files changed, 45 insertions(+) create mode 100644 tests/parallel_hash_map_test.cc diff --git a/parallel_hashmap/phmap.h b/parallel_hashmap/phmap.h index f2b596f..8ae2ca6 100644 --- a/parallel_hashmap/phmap.h +++ b/parallel_hashmap/phmap.h @@ -3408,6 +3408,16 @@ public: return true; } + template + bool if_contains(const key_arg& key, F&& f) { + typename Lockable::SharedLock m; + auto it = const_cast(this)->find(key, hash(key), m); + if (it == this->end()) + return false; + std::forward(f)(Policy::value(&*it)); + return true; + } + template MappedReference

operator[](key_arg&& key) { return Policy::value(&*try_emplace(std::forward(key)).first); diff --git a/tests/flat_hash_map_test.cc b/tests/flat_hash_map_test.cc index 316c9f7..5f0e57f 100644 --- a/tests/flat_hash_map_test.cc +++ b/tests/flat_hash_map_test.cc @@ -244,6 +244,7 @@ TEST(THIS_TEST_NAME, MergeExtractInsert) { m.insert(std::move(node)); EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 17), Pair(2, 9))); } + #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__EMSCRIPTEN__) && defined(PHMAP_HAVE_STD_ANY) TEST(THIS_TEST_NAME, Any) { ThisMap m; diff --git a/tests/parallel_flat_hash_map_test.cc b/tests/parallel_flat_hash_map_test.cc index d1e6288..500bc3c 100644 --- a/tests/parallel_flat_hash_map_test.cc +++ b/tests/parallel_flat_hash_map_test.cc @@ -2,3 +2,4 @@ #define THIS_TEST_NAME ParallelFlatHashMap #include "flat_hash_map_test.cc" +#include "parallel_hash_map_test.cc" diff --git a/tests/parallel_hash_map_test.cc b/tests/parallel_hash_map_test.cc new file mode 100644 index 0000000..b729118 --- /dev/null +++ b/tests/parallel_hash_map_test.cc @@ -0,0 +1,32 @@ +#ifndef THIS_HASH_MAP + #define THIS_HASH_MAP parallel_flat_hash_map + #define THIS_TEST_NAME ParallelFlatHashMap +#endif + +namespace phmap { +namespace container_internal { +namespace { + +TEST(THIS_TEST_NAME, ThreadSafeContains) { + // We can't test mutable keys, or non-copyable keys with ThisMap. + // Test that the nodes have the proper API. + ThisMap m = { {1, 7}, {2, 9} }; + auto val = 0; + EXPECT_TRUE(m.contains(1, val)); + EXPECT_EQ(val, 7); + + EXPECT_FALSE(m.contains(3, val)); + +#if __cplusplus > 199711L + auto func = [&val](int& v) { val = v; }; + EXPECT_TRUE(m.if_contains(2, func)); + EXPECT_EQ(val, 9); + + EXPECT_FALSE(m.if_contains(3, func)); +#endif + +} + +} // namespace +} // namespace container_internal +} // namespace phmap diff --git a/tests/parallel_node_hash_map_test.cc b/tests/parallel_node_hash_map_test.cc index 615a0ba..ea51222 100644 --- a/tests/parallel_node_hash_map_test.cc +++ b/tests/parallel_node_hash_map_test.cc @@ -2,3 +2,4 @@ #define THIS_TEST_NAME ParallelNodeHashMap #include "flat_hash_map_test.cc" +#include "parallel_hash_map_test.cc"