added unordered_flat_map(concurrent_flat_map&&)

This commit is contained in:
joaquintides
2023-07-22 17:59:01 +02:00
committed by Christian Mazakas
parent 48ff743d06
commit 6bf84067b3
5 changed files with 78 additions and 15 deletions

View File

@ -15,6 +15,7 @@
#include <boost/unordered/detail/foa/concurrent_table.hpp>
#include <boost/unordered/detail/foa/flat_map_types.hpp>
#include <boost/unordered/detail/type_traits.hpp>
#include <boost/unordered/unordered_flat_map_fwd.hpp>
#include <boost/container_hash/hash.hpp>
#include <boost/core/allocator_access.hpp>
@ -84,6 +85,9 @@ namespace boost {
template <class Key2, class T2, class Hash2, class Pred2,
class Allocator2>
friend class concurrent_flat_map;
template <class Key2, class T2, class Hash2, class Pred2,
class Allocator2>
friend class unordered_flat_map;
using type_policy = detail::foa::flat_map_types<Key, T>;

View File

@ -281,6 +281,13 @@ struct concurrent_table_arrays:table_arrays<Value,Group,SizePolicy>
template<typename Allocator>
static void delete_(Allocator& al,concurrent_table_arrays& arrays)noexcept
{
delete_group_access(al,arrays);
super::delete_(al,arrays);
}
template<typename Allocator>
static void delete_group_access(Allocator& al,concurrent_table_arrays& arrays)noexcept
{
if(arrays.elements){
using access_alloc=
@ -294,7 +301,6 @@ struct concurrent_table_arrays:table_arrays<Value,Group,SizePolicy>
aal,pointer_traits::pointer_to(*arrays.group_accesses),
arrays.groups_size_mask+1);
}
super::delete_(al,arrays);
}
group_access *group_accesses;
@ -391,6 +397,9 @@ inline void swap(atomic_size_control& x,atomic_size_control& y)
* over.
*/
template<typename,typename,typename,typename>
class table; /* concurrent/non-concurrent interop */
template <typename TypePolicy,typename Hash,typename Pred,typename Allocator>
using concurrent_table_core_impl=table_core<
TypePolicy,group15<atomic_integral>,concurrent_table_arrays,
@ -413,10 +422,6 @@ class concurrent_table:
using super::N;
using prober=typename super::prober;
template<
typename TypePolicy2,typename Hash2,typename Pred2,typename Allocator2>
friend class concurrent_table;
public:
using key_type=typename super::key_type;
using init_type=typename super::init_type;
@ -875,6 +880,9 @@ public:
}
private:
template<typename,typename,typename,typename> friend class concurrent_table;
template<typename,typename,typename,typename> friend class table;
using mutex_type=rw_spinlock;
using multimutex_type=multimutex<mutex_type,128>; // TODO: adapt 128 to the machine
using shared_lock_guard=shared_lock<mutex_type>;

View File

@ -1282,6 +1282,17 @@ public:
size_ctrl{initial_max_load(),0}
{}
/* bare transfer ctor for concurrent/non-concurrent interop */
table_core(
Hash&& h_,Pred&& pred_,Allocator&& al_,
const arrays_type& arrays_,const size_ctrl_type& size_ctrl_):
hash_base{empty_init,h_},
pred_base{empty_init,pred_},
allocator_base{empty_init,al_},
arrays(arrays_),size_ctrl(size_ctrl_)
{}
table_core(const table_core& x):
table_core{x,alloc_traits::select_on_container_copy_construction(x.al())}{}
@ -1290,14 +1301,11 @@ public:
std::is_nothrow_move_constructible<Hash>::value&&
std::is_nothrow_move_constructible<Pred>::value&&
std::is_nothrow_move_constructible<Allocator>::value):
hash_base{empty_init,std::move(x.h())},
pred_base{empty_init,std::move(x.pred())},
allocator_base{empty_init,std::move(x.al())},
arrays(x.arrays),size_ctrl(x.size_ctrl)
table_core{
std::move(x.h()),std::move(x.pred()),std::move(x.al()),
x.arrays,x.size_ctrl}
{
x.arrays=x.new_arrays(0);
x.size_ctrl.ml=x.initial_max_load();
x.size_ctrl.size=0;
x.empty_initialize();
}
table_core(const table_core& x,const Allocator& al_):
@ -1336,6 +1344,13 @@ public:
delete_arrays(arrays);
}
void empty_initialize()noexcept
{
arrays=new_arrays(0);
size_ctrl.ml=initial_max_load();
size_ctrl.size=0;
}
table_core& operator=(const table_core& x)
{
BOOST_UNORDERED_STATIC_ASSERT_HASH_PRED(Hash, Pred)
@ -1802,9 +1817,10 @@ private:
table_core(Hash&& h_,Pred&& pred_,const Allocator& al_):
hash_base{empty_init,std::move(h_)},
pred_base{empty_init,std::move(pred_)},
allocator_base{empty_init,al_},arrays(new_arrays(0)),
size_ctrl{initial_max_load(),0}
{}
allocator_base{empty_init,al_}
{
empty_initialize();
}
arrays_type new_arrays(std::size_t n)
{

View File

@ -264,6 +264,9 @@ private:
* checking is done by boost::unordered_(flat|node)_(map|set).
*/
template<typename,typename,typename,typename>
class concurrent_table; /* concurrent/non-concurrent interop */
template <typename TypePolicy,typename Hash,typename Pred,typename Allocator>
using table_core_impl=
table_core<TypePolicy,group15<plain_integral>,table_arrays,
@ -284,6 +287,8 @@ class table:table_core_impl<TypePolicy,Hash,Pred,Allocator>
using group_type=typename super::group_type;
using super::N;
using prober=typename super::prober;
using arrays_type=typename super::arrays_type;
using size_ctrl_type=typename super::size_ctrl_type;
using locator=typename super::locator;
public:
@ -323,6 +328,8 @@ public:
table(table&& x)=default;
table(const table& x,const Allocator& al_):super{x,al_}{}
table(table&& x,const Allocator& al_):super{std::move(x),al_}{}
table(concurrent_table<TypePolicy,Hash,Pred,Allocator>&& x):
table(std::move(x),x.exclusive_access()){}
~table()=default;
table& operator=(const table& x)=default;
@ -496,6 +503,27 @@ public:
friend bool operator!=(const table& x,const table& y){return !(x==y);}
private:
template<typename,typename,typename,typename> friend class concurrent_table;
using compatible_concurrent_table=
concurrent_table<TypePolicy,Hash,Pred,Allocator>;
table(
compatible_concurrent_table&& x,
typename compatible_concurrent_table::exclusive_lock_guard):
super{
std::move(x.h()),std::move(x.pred()),std::move(x.al()),
arrays_type{
x.arrays.groups_size_index,x.arrays.groups_size_mask,
reinterpret_cast<group_type*>(x.arrays.groups),
reinterpret_cast<value_type*>(x.arrays.elements)},
size_ctrl_type{
x.size_ctrl.ml,x.size_ctrl.size}}
{
typename compatible_concurrent_table::arrays_type::delete_group_access(
this->al(),x.arrays);
x.empty_initialize();
}
struct erase_on_exit
{
erase_on_exit(table& x_,const_iterator it_):x{x_},it{it_}{}

View File

@ -10,6 +10,7 @@
#pragma once
#endif
#include <boost/unordered/concurrent_flat_map_fwd.hpp>
#include <boost/unordered/detail/foa/flat_map_types.hpp>
#include <boost/unordered/detail/foa/table.hpp>
#include <boost/unordered/detail/type_traits.hpp>
@ -173,6 +174,12 @@ namespace boost {
{
}
unordered_flat_map(
concurrent_flat_map<Key, T, Hash, KeyEqual, Allocator>&& other)
: table_(std::move(other.table_))
{
}
~unordered_flat_map() = default;
unordered_flat_map& operator=(unordered_flat_map const& other)