Feature/concurrent node containers (#271)

* added concurrent node containers

* removed spurious typename

* added missing includes

* avoided unused param warning

* worked around Clang bug

* s/{}/() to work around GCC4.8 problems with aggregate initialization

* used /bigobj for cfoa/visit_tests.cpp

* suppressed localized maybe-uninitialized warnings

* fixed comments

* added /bigobj to cfoa/insert_tests.cpp

* instrumented double exact comparison to spot a spurious error

* fixed pedantic error

* refactored byte_span machinery

* compromised on sub-epsilon equality for doubles that should be identical

* documented boost::concurrent_node_(map|set)

* added concurrent_node_set

* added missing AlternativeType

* tested empty node insertion

* tested node_handle allocator management

* added nonassignable_allocator and node_handle_allocator_swap_tests

* fixed warning disabling

* silenced spurious GCC warning

* broadened scope of previous pragma

* broadened even more

* worked around spurious constexpr-related msvc-14.0 bug
https://godbolt.org/z/v78545Ebf

* added workaround back

* replaced previous workaround with built-in one

* added workaround back on top of built-in solution (which doesn't work 100% of the time)
This commit is contained in:
joaquintides
2024-08-25 18:34:58 +02:00
committed by GitHub
parent 35bdabf259
commit f734e399e3
58 changed files with 7007 additions and 338 deletions

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Copyright (C) 2024 Braden Ganetsky
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,6 +9,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#include <boost/core/ignore_unused.hpp>
@@ -80,11 +82,8 @@ namespace {
}
template <class T, class X> void operator()(std::vector<T>& values, X& x)
{
static constexpr auto value_type_cardinality =
value_cardinality<typename X::value_type>::value;
call_impl(values, x);
BOOST_TEST_GE(raii::move_constructor, value_type_cardinality * x.size());
BOOST_TEST_GE(raii::move_constructor, x.size());
}
} lvalue_emplacer;
@@ -197,7 +196,12 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, 0u);
BOOST_TEST_EQ(raii::copy_constructor, value_type_cardinality * x.size());
BOOST_TEST_GT(raii::move_constructor, 0u);
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else {
BOOST_TEST_GT(raii::move_constructor, 0u);
}
BOOST_TEST_EQ(raii::copy_assignment, 0u);
BOOST_TEST_EQ(raii::move_assignment, 0u);
@@ -208,8 +212,8 @@ namespace {
{
template <class T, class X> void operator()(std::vector<T>& values, X& x)
{
static constexpr auto value_type_cardinality =
value_cardinality<typename X::value_type>::value;
static constexpr auto input_type_nonconst_cardinality =
value_nonconst_cardinality<T>::value;
std::atomic<std::uint64_t> num_inserts{0};
thread_runner(values, [&x, &num_inserts](boost::span<T> s) {
@@ -235,10 +239,18 @@ namespace {
} else {
BOOST_TEST_EQ(raii::copy_constructor, 0u);
}
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(
raii::move_constructor, input_type_nonconst_cardinality * x.size());
}
else {
BOOST_TEST_GT(
raii::move_constructor, input_type_nonconst_cardinality * x.size());
}
#if defined(BOOST_MSVC)
#pragma warning(pop) // C4127
#endif
BOOST_TEST_GT(raii::move_constructor, value_type_cardinality * x.size());
BOOST_TEST_EQ(raii::copy_assignment, 0u);
BOOST_TEST_EQ(raii::move_assignment, 0u);
@@ -280,7 +292,9 @@ namespace {
}
boost::unordered::concurrent_flat_map<raii, raii>* map;
boost::unordered::concurrent_node_map<raii, raii>* node_map;
boost::unordered::concurrent_flat_set<raii>* set;
boost::unordered::concurrent_node_set<raii>* node_set;
} // namespace
@@ -292,7 +306,7 @@ using test::sequential;
UNORDERED_TEST(
emplace,
((map)(set))
((map)(node_map)(set)(node_set))
((value_type_generator_factory)(init_type_generator_factory))
((lvalue_emplacer)(norehash_lvalue_emplacer)
(lvalue_emplace_or_cvisit)(lvalue_emplace_or_visit)(copy_emplacer)(move_emplacer))
@@ -455,6 +469,8 @@ namespace {
boost::unordered::concurrent_flat_map<counted_key_type, counted_value_type>*
test_counted_flat_map = {};
boost::unordered::concurrent_node_map<counted_key_type, counted_value_type>*
test_counted_node_map = {};
} // namespace
@@ -462,7 +478,7 @@ namespace {
UNORDERED_TEST(
emplace_map_key_value,
((test_counted_flat_map))
((test_counted_flat_map)(test_counted_node_map))
((copy)(move))
((counted_key_checker)(converting_key_checker))
((counted_value_checker)(converting_value_checker))