diff --git a/.gitmodules b/.gitmodules index c28bb72c3..55ea47e8d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -23,3 +23,6 @@ [submodule "third_party/wide-integer"] path = third_party/wide-integer url = ../../ckormanyos/wide-integer.git +[submodule "third_party/parallel-hashmap"] + path = third_party/parallel-hashmap + url = ../../greg7mdp/parallel-hashmap.git diff --git a/libgringo/CMakeLists.txt b/libgringo/CMakeLists.txt index b9a60a717..c0c935d63 100644 --- a/libgringo/CMakeLists.txt +++ b/libgringo/CMakeLists.txt @@ -126,7 +126,7 @@ set(source # ]]] add_library(libgringo STATIC ${header} ${source}) -target_link_libraries(libgringo PUBLIC libpotassco libreify tsl::ordered_map tsl::hopscotch_map tsl::sparse_map tl::optional mpark::variant math::wide_integer) +target_link_libraries(libgringo PUBLIC libpotassco libreify tsl::ordered_map tsl::hopscotch_map tsl::sparse_map tl::optional mpark::variant math::wide_integer grep::phmap) target_include_directories(libgringo PUBLIC "$" diff --git a/libgringo/src/symbol.cc b/libgringo/src/symbol.cc index 0da667d31..c33bf7f01 100644 --- a/libgringo/src/symbol.cc +++ b/libgringo/src/symbol.cc @@ -24,10 +24,12 @@ #include #include +#include + +#include + #include #include -#include -#include #ifdef _MSC_VER #pragma warning(disable : 4200) // nonstandard extension used: zero-sized array in struct/union @@ -79,28 +81,22 @@ String toString(uint64_t rep) { return String::fromRep(ptr(rep)); } template struct UniqueConstruct { public: - using Set = hash_set; + using Set = + phmap::parallel_flat_hash_set, 6, std::mutex>; template static T const &construct(U &&x) { - // TODO: in C++17 this can use a read/write lock to not block reading threads - size_t hash = typename T::Hash{}(x); - std::lock_guard g(mutex_); - auto it = set_.find(x, hash); - if (it != set_.end()) { - return *it; - } - return *set_.insert(T{std::forward(x), hash}).first; + size_t raw_hash = typename T::Hash{}(x); + size_t mixed_hash = phmap::phmap_mix()(raw_hash); + return *set_.lazy_emplace_with_hash(x, mixed_hash, + [&x, raw_hash](auto const &ctor) { ctor(std::forward(x), raw_hash); }); } private: - static Set set_; // NOLINT - static std::mutex mutex_; // NOLINT + static Set set_; // NOLINT }; template typename UniqueConstruct::Set UniqueConstruct::set_; // NOLINT -template typename std::mutex UniqueConstruct::mutex_; // NOLINT - template T const &construct_unique(U &&x) { return UniqueConstruct::construct(std::forward(x)); } @@ -112,8 +108,9 @@ class MSig { using Cons = std::pair; struct Hash { + using is_transparent = void; size_t operator()(MSig const &sig) const { return sig.hash_; } - size_t operator()(Cons const &sig) const { return hash_mix(get_value_hash(sig)); } + size_t operator()(Cons const &sig) const { return get_value_hash(sig); } }; struct EqualTo { using is_transparent = void; @@ -190,9 +187,10 @@ class MFun { using Cons = std::pair; struct Hash { + using is_transparent = void; size_t operator()(MFun const &a) const { return a.fun_->hash(); } size_t operator()(Cons const &a) const { - return hash_mix(get_value_hash(a.first, hash_range(begin(a.second), end(a.second)))); + return get_value_hash(a.first, hash_range(begin(a.second), end(a.second))); } }; struct EqualTo { @@ -285,9 +283,10 @@ class String::Impl { class String::Impl::MString { public: struct Hash { + using is_transparent = void; size_t operator()(MString const &str) const { return str.str_->hash(); } - size_t operator()(char const *str) const { return hash_mix(strhash(str)); } - size_t operator()(StringSpan const &str) const { return hash_mix(strhash(str)); } + size_t operator()(char const *str) const { return strhash(str); } + size_t operator()(StringSpan const &str) const { return strhash(str); } }; struct EqualTo { using is_transparent = void; diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index 57bdd993a..ad7d86a4c 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -30,3 +30,7 @@ add_library(mpark::variant ALIAS variant) add_library(wide_integer INTERFACE) target_include_directories(wide_integer INTERFACE $) add_library(math::wide_integer ALIAS wide_integer) + +add_library(phmap INTERFACE) +target_include_directories(phmap INTERFACE $) +add_library(grep::phmap ALIAS phmap) diff --git a/third_party/parallel-hashmap b/third_party/parallel-hashmap new file mode 160000 index 000000000..8442f1c82 --- /dev/null +++ b/third_party/parallel-hashmap @@ -0,0 +1 @@ +Subproject commit 8442f1c82cad04c026e3db4959c6b7a5396f982a