Skip to content

Commit

Permalink
Merge pull request #165 from greg7mdp/disable_locking
Browse files Browse the repository at this point in the history
Allow swap() to work with parallel hash maps/sets with different mutex types, so you can use the same container with or without locking.
  • Loading branch information
greg7mdp committed Sep 12, 2022
2 parents f06b398 + f0409c6 commit 3bde3fb
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 11 deletions.
37 changes: 26 additions & 11 deletions parallel_hashmap/phmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -3372,6 +3372,11 @@ class parallel_hash_set
fCallback(set);
}

// unsafe, for internal use only
Inner& get_inner(size_t idx) {
return sets_[idx];
}

// Extension API: support for heterogeneous keys.
//
// std::unordered_set<std::string> s;
Expand Down Expand Up @@ -3473,15 +3478,20 @@ class parallel_hash_set
return it == end() ? node_type() : extract(const_iterator{it});
}

void swap(parallel_hash_set& that) noexcept(
IsNoThrowSwappable<EmbeddedSet>() &&
(!AllocTraits::propagate_on_container_swap::value ||
IsNoThrowSwappable<allocator_type>())) {
template<class Mtx2_>
void swap(parallel_hash_set<N, RefSet, Mtx2_, Policy, Hash, Eq, Alloc>& that)
noexcept(IsNoThrowSwappable<EmbeddedSet>() &&
(!AllocTraits::propagate_on_container_swap::value ||
IsNoThrowSwappable<allocator_type>()))
{
using std::swap;
using Lockable2 = phmap::LockableImpl<Mtx2_>;

for (size_t i=0; i<num_tables; ++i)
{
typename Lockable::UniqueLocks l(sets_[i], that.sets_[i]);
swap(sets_[i].set_, that.sets_[i].set_);
typename Lockable::UniqueLock l(sets_[i]);
typename Lockable2::UniqueLock l2(that.get_inner(i));
swap(sets_[i].set_, that.get_inner(i).set_);
}
}

Expand Down Expand Up @@ -3620,8 +3630,11 @@ class parallel_hash_set
return !(a == b);
}

template<class Mtx2_>
friend void swap(parallel_hash_set& a,
parallel_hash_set& b) noexcept(noexcept(a.swap(b))) {
parallel_hash_set<N, RefSet, Mtx2_, Policy, Hash, Eq, Alloc>& b)
noexcept(noexcept(a.swap(b)))
{
a.swap(b);
}

Expand Down Expand Up @@ -3700,14 +3713,16 @@ class parallel_hash_set

// TODO(alkis): Optimize this assuming *this and that don't overlap.
// --------------------------------------------------------------------
parallel_hash_set& move_assign(parallel_hash_set&& that, std::true_type) {
parallel_hash_set tmp(std::move(that));
template<class Mtx2_>
parallel_hash_set& move_assign(parallel_hash_set<N, RefSet, Mtx2_, Policy, Hash, Eq, Alloc>&& that, std::true_type) {
parallel_hash_set<N, RefSet, Mtx2_, Policy, Hash, Eq, Alloc> tmp(std::move(that));
swap(tmp);
return *this;
}

parallel_hash_set& move_assign(parallel_hash_set&& that, std::false_type) {
parallel_hash_set tmp(std::move(that), alloc_ref());
template<class Mtx2_>
parallel_hash_set& move_assign(parallel_hash_set<N, RefSet, Mtx2_, Policy, Hash, Eq, Alloc>&& that, std::false_type) {
parallel_hash_set<N, RefSet, Mtx2_, Policy, Hash, Eq, Alloc> tmp(std::move(that), alloc_ref());
swap(tmp);
return *this;
}
Expand Down
10 changes: 10 additions & 0 deletions tests/flat_hash_map_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
#define THIS_EXTRA_TPL_PARAMS
#endif

#ifndef THIS_EXTRA_TPL_PARAMS_NULLMUTEX
#define THIS_EXTRA_TPL_PARAMS_NULLMUTEX
#endif

#include "parallel_hashmap/phmap.h"

#if defined(PHMAP_HAVE_STD_ANY)
Expand Down Expand Up @@ -62,6 +66,12 @@ template <class K, class V, class H = phmap::priv::hash_default_hash<K>,
class Alloc = phmap::priv::Allocator<
phmap::priv::Pair<const K, V>>>
using ThisMap = THIS_HASH_MAP<K, V, H, Eq, Alloc THIS_EXTRA_TPL_PARAMS>;

template <class K, class V, class H = phmap::priv::hash_default_hash<K>,
class Eq = phmap::priv::hash_default_eq<K>,
class Alloc = phmap::priv::Allocator<
phmap::priv::Pair<const K, V>>>
using ThisMap_NullMutex = THIS_HASH_MAP<K, V, H, Eq, Alloc THIS_EXTRA_TPL_PARAMS_NULLMUTEX>;

static_assert(!std::is_standard_layout<NonStandardLayout>(), "");

Expand Down
2 changes: 2 additions & 0 deletions tests/parallel_flat_hash_map_mutex_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@
#define THIS_EXTRA_TPL_PARAMS , 4, boost::upgrade_mutex
#endif

#define THIS_EXTRA_TPL_PARAMS_NULLMUTEX , 4, phmap::NullMutex

#include "parallel_hash_map_test.cc"
18 changes: 18 additions & 0 deletions tests/parallel_hash_map_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@ namespace phmap {
namespace priv {
namespace {

TEST(THIS_TEST_NAME, Swap) {
using Map = ThisMap<int, int>;
using MapB = ThisMap_NullMutex<int, int>;

Map t;
EXPECT_TRUE(t.find(0) == t.end());
auto res = t.emplace(0, 1);
EXPECT_TRUE(res.second);
EXPECT_EQ(1, t.size());
MapB u;
t.swap(u);
EXPECT_EQ(0, t.size());
EXPECT_EQ(1, u.size());
EXPECT_TRUE(t.find(0) == t.end());
EXPECT_TRUE(u[0] == 1);
}


TEST(THIS_TEST_NAME, IfContains) {
// ----------------
// test if_contains
Expand Down

0 comments on commit 3bde3fb

Please sign in to comment.