Update work-in-progress testing hash container to latest Intrusive improvements

This commit is contained in:
Ion Gaztañaga
2022-05-04 23:43:27 +02:00
parent d004191b45
commit d6badf63b0
2 changed files with 63 additions and 35 deletions

View File

@ -97,6 +97,18 @@ struct iiterator_node_value_type< base_node<T, intrusive_hash_table_hook<VoidPoi
typedef T type;
};
template<class Options>
struct get_hash_opt
{
typedef Options type;
};
template<>
struct get_hash_opt<void>
{
typedef hash_assoc_defaults type;
};
template<class, class KeyOfValue>
struct hash_key_of_value
@ -141,7 +153,7 @@ class hash_insert_equal_end_hint_functor
namespace dtl {
template< class NodeType, class NodeHashType, class NodeCompareType
, class SizeType, class HookType>
, class SizeType, class HookType, bool CompareHash, bool CacheBegin, bool LinearBuckets>
struct intrusive_hash_table_dispatch
{
typedef typename dtl::bi::make_hashtable
@ -151,10 +163,14 @@ struct intrusive_hash_table_dispatch
,dtl::bi::base_hook<HookType>
,dtl::bi::constant_time_size<true>
,dtl::bi::size_type<SizeType>
,dtl::bi::cache_begin<CacheBegin>
,dtl::bi::compare_hash<CompareHash>
,dtl::bi::linear_buckets<LinearBuckets>
>::type type;
};
template<class Allocator, class ValueHash, class ValueCompare, bool StoreHash>
template<class Allocator, class ValueHash, class ValueCompare
,bool StoreHash, bool CacheBegin, bool LinearBuckets>
struct intrusive_hash_table_type
{
private:
@ -174,11 +190,12 @@ struct intrusive_hash_table_type
//provoke an early instantiation of node_t that could ruin recursive
//hash_table definitions, so retype the complete type to avoid any problem.
typedef typename intrusive_hash_table_hook
<void_pointer, StoreHash>::type hook_type;
<void_pointer, StoreHash>::type hook_type;
public:
typedef typename intrusive_hash_table_dispatch
< node_t, node_hash_type, node_equal_type
, size_type, hook_type>::type type;
, size_type, hook_type, StoreHash
, CacheBegin, LinearBuckets>::type type;
};
} //namespace dtl {
@ -241,19 +258,6 @@ class HashRecyclingCloner
intrusive_container &m_icont;
};
template<class Options>
struct get_hash_table_opt
{
typedef Options type;
};
template<>
struct get_hash_table_opt<void>
{
typedef hash_assoc_defaults type;
};
template <class KeyOfValue, class KeyHash, class KeyEqual, class Allocator, class Options>
struct hash_table_types
{
@ -266,10 +270,12 @@ struct hash_table_types
typedef tree_value_compare
< typename allocator_traits<Allocator>::pointer
, KeyEqual, key_of_value_t, bool> ValEqual;
typedef typename get_hash_table_opt<Options>::type options_type;
typedef typename get_hash_opt<Options>::type options_type;
typedef typename dtl::intrusive_hash_table_type
< Allocator, ValHash, ValEqual
, options_type::store_hash
, options_type::cache_begin
, options_type::linear_buckets
>::type Icont;
typedef typename Icont::bucket_type bucket_type;
typedef typename Icont::bucket_traits bucket_traits;
@ -283,9 +289,17 @@ struct hash_table_types
};
template<class Bucket, std::size_t N>
struct static_buckets
{
static const std::size_t size = N;
Bucket buckets_[N];
};
template <class T, class KeyOfValue, class KeyHash, class KeyEqual, class Allocator, class Options>
class hash_table
: public hash_table_types<KeyOfValue, KeyHash, KeyEqual, Allocator, Options>::bucket_type
: public static_buckets< typename hash_table_types<KeyOfValue, KeyHash, KeyEqual, Allocator, Options>::bucket_type
, hash_table_types<KeyOfValue, KeyHash, KeyEqual, Allocator, Options>::Icont::bucket_overhead+1u>
, public hash_table_types<KeyOfValue, KeyHash, KeyEqual, Allocator, Options>::bucket_holder_t
, public hash_table_types<KeyOfValue, KeyHash, KeyEqual, Allocator, Options>::AllocHolder
{
@ -315,6 +329,8 @@ class hash_table
typedef typename hash_table_types
<KeyOfValue, KeyHash, KeyEqual, Allocator, Options>
::bucket_holder_t bucket_holder_t;
typedef static_buckets< typename Icont::bucket_type
, Icont::bucket_overhead + 1u > static_buckets_t;
BOOST_COPYABLE_AND_MOVABLE(hash_table)
@ -366,7 +382,7 @@ class hash_table
public:
BOOST_CONTAINER_FORCEINLINE hash_table()
: AllocHolder(bucket_traits(this, 1))
: AllocHolder(bucket_traits( ((static_buckets_t&)*this).buckets_, static_buckets_t::size))
{ this->reserve(0); }
BOOST_CONTAINER_FORCEINLINE explicit hash_table(const allocator_type& a)
@ -731,10 +747,7 @@ class hash_table
(BOOST_FWD_REF(MovableConvertible) v, insert_commit_data &data)
{
NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(v));
scoped_node_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_unique_commit(*tmp, data));
destroy_deallocator.release();
return ret;
return iterator(this->icont().insert_unique_commit(*tmp, data));
}
template<class MovableConvertible>
@ -950,7 +963,8 @@ class hash_table
//IOG temp
BOOST_CONTAINER_FORCEINLINE iterator insert(const value_type& v)
{
this->reserve(this->size() + 1u);
if(BOOST_UNLIKELY(this->size() == this->bucket_count()))
this->reserve(this->size() + 1u);
return this->insert_unique(v).first;
}
@ -1005,7 +1019,7 @@ class hash_table
return std::pair<iterator, bool>(iterator(ret.first), ret.second);
}
void erase(const_iterator position)
BOOST_CONTAINER_FORCEINLINE void erase(const_iterator position)
{
BOOST_ASSERT(position != this->cend() && (priv_is_linked)(position));
return this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()));
@ -1185,11 +1199,11 @@ class hash_table
void reserve(size_type n)
{
if (!n || this->bucket_count() < n) {
if (this->bucket_count() < n) {
std::size_t sc = Icont::suggested_upper_bucket_count(n);
bucket_holder_t& this_buckets = *this;
bucket_holder_t new_buckets(sc, this_buckets.get_allocator());
this->icont().rehash(bucket_traits(new_buckets.data(), sc));
bucket_holder_t new_buckets(sc + Icont::bucket_overhead, this_buckets.get_allocator());
this->icont().rehash(bucket_traits(new_buckets.data(), new_buckets.size()));
this_buckets.swap(new_buckets);
}
}

View File

@ -113,20 +113,31 @@ using tree_assoc_options_t = typename boost::container::tree_assoc_options<Optio
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template<bool StoreHash>
template<bool StoreHash, bool CacheBegin, bool LinearBuckets>
struct hash_opt
{
static const bool store_hash = StoreHash;
static const bool store_hash = StoreHash;
static const bool cache_begin = CacheBegin;
static const bool linear_buckets = LinearBuckets;
};
typedef hash_opt<false> hash_assoc_defaults;
typedef hash_opt<false, false, false> hash_assoc_defaults;
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//!This option setter specifies if node size is optimized
//!storing rebalancing data masked into pointers for ordered associative containers
//!This option setter specifies if nodes also store the hash value
//!so that search and rehashing for hash-expensive types is improved.
//!This option might degrade performance for easy to hash types (like integers)
BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash)
//!This option setter specifies if the container will cache the first
//!non-empty bucket so that begin() is O(1) instead of searching for the
//!first non-empty bucket (which can be O(bucket_size()))
BOOST_INTRUSIVE_OPTION_CONSTANT(cache_begin, bool, Enabled, cache_begin)
BOOST_INTRUSIVE_OPTION_CONSTANT(linear_buckets, bool, Enabled, linear_buckets)
//! Helper metafunction to combine options into a single type to be used
//! by \c boost::container::hash_set, \c boost::container::hash_multiset
//! \c boost::container::hash_map and \c boost::container::hash_multimap.
@ -147,7 +158,10 @@ struct hash_assoc_options
Options...
#endif
>::type packed_options;
typedef hash_opt<packed_options::store_hash> implementation_defined;
typedef hash_opt<packed_options::store_hash
,packed_options::cache_begin
,packed_options::linear_buckets
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};