mirror of
https://github.com/boostorg/container.git
synced 2025-08-01 05:24:31 +02:00
Update work-in-progress testing hash container to latest Intrusive improvements
This commit is contained in:
@@ -97,6 +97,18 @@ struct iiterator_node_value_type< base_node<T, intrusive_hash_table_hook<VoidPoi
|
|||||||
typedef T type;
|
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>
|
template<class, class KeyOfValue>
|
||||||
struct hash_key_of_value
|
struct hash_key_of_value
|
||||||
@@ -141,7 +153,7 @@ class hash_insert_equal_end_hint_functor
|
|||||||
namespace dtl {
|
namespace dtl {
|
||||||
|
|
||||||
template< class NodeType, class NodeHashType, class NodeCompareType
|
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
|
struct intrusive_hash_table_dispatch
|
||||||
{
|
{
|
||||||
typedef typename dtl::bi::make_hashtable
|
typedef typename dtl::bi::make_hashtable
|
||||||
@@ -151,10 +163,14 @@ struct intrusive_hash_table_dispatch
|
|||||||
,dtl::bi::base_hook<HookType>
|
,dtl::bi::base_hook<HookType>
|
||||||
,dtl::bi::constant_time_size<true>
|
,dtl::bi::constant_time_size<true>
|
||||||
,dtl::bi::size_type<SizeType>
|
,dtl::bi::size_type<SizeType>
|
||||||
|
,dtl::bi::cache_begin<CacheBegin>
|
||||||
|
,dtl::bi::compare_hash<CompareHash>
|
||||||
|
,dtl::bi::linear_buckets<LinearBuckets>
|
||||||
>::type type;
|
>::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
|
struct intrusive_hash_table_type
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -174,11 +190,12 @@ struct intrusive_hash_table_type
|
|||||||
//provoke an early instantiation of node_t that could ruin recursive
|
//provoke an early instantiation of node_t that could ruin recursive
|
||||||
//hash_table definitions, so retype the complete type to avoid any problem.
|
//hash_table definitions, so retype the complete type to avoid any problem.
|
||||||
typedef typename intrusive_hash_table_hook
|
typedef typename intrusive_hash_table_hook
|
||||||
<void_pointer, StoreHash>::type hook_type;
|
<void_pointer, StoreHash>::type hook_type;
|
||||||
public:
|
public:
|
||||||
typedef typename intrusive_hash_table_dispatch
|
typedef typename intrusive_hash_table_dispatch
|
||||||
< node_t, node_hash_type, node_equal_type
|
< 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 {
|
} //namespace dtl {
|
||||||
@@ -241,19 +258,6 @@ class HashRecyclingCloner
|
|||||||
intrusive_container &m_icont;
|
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>
|
template <class KeyOfValue, class KeyHash, class KeyEqual, class Allocator, class Options>
|
||||||
struct hash_table_types
|
struct hash_table_types
|
||||||
{
|
{
|
||||||
@@ -266,10 +270,12 @@ struct hash_table_types
|
|||||||
typedef tree_value_compare
|
typedef tree_value_compare
|
||||||
< typename allocator_traits<Allocator>::pointer
|
< typename allocator_traits<Allocator>::pointer
|
||||||
, KeyEqual, key_of_value_t, bool> ValEqual;
|
, 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
|
typedef typename dtl::intrusive_hash_table_type
|
||||||
< Allocator, ValHash, ValEqual
|
< Allocator, ValHash, ValEqual
|
||||||
, options_type::store_hash
|
, options_type::store_hash
|
||||||
|
, options_type::cache_begin
|
||||||
|
, options_type::linear_buckets
|
||||||
>::type Icont;
|
>::type Icont;
|
||||||
typedef typename Icont::bucket_type bucket_type;
|
typedef typename Icont::bucket_type bucket_type;
|
||||||
typedef typename Icont::bucket_traits bucket_traits;
|
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>
|
template <class T, class KeyOfValue, class KeyHash, class KeyEqual, class Allocator, class Options>
|
||||||
class hash_table
|
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>::bucket_holder_t
|
||||||
, public hash_table_types<KeyOfValue, KeyHash, KeyEqual, Allocator, Options>::AllocHolder
|
, public hash_table_types<KeyOfValue, KeyHash, KeyEqual, Allocator, Options>::AllocHolder
|
||||||
{
|
{
|
||||||
@@ -315,6 +329,8 @@ class hash_table
|
|||||||
typedef typename hash_table_types
|
typedef typename hash_table_types
|
||||||
<KeyOfValue, KeyHash, KeyEqual, Allocator, Options>
|
<KeyOfValue, KeyHash, KeyEqual, Allocator, Options>
|
||||||
::bucket_holder_t bucket_holder_t;
|
::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)
|
BOOST_COPYABLE_AND_MOVABLE(hash_table)
|
||||||
@@ -366,7 +382,7 @@ class hash_table
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
BOOST_CONTAINER_FORCEINLINE hash_table()
|
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); }
|
{ this->reserve(0); }
|
||||||
|
|
||||||
BOOST_CONTAINER_FORCEINLINE explicit hash_table(const allocator_type& a)
|
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)
|
(BOOST_FWD_REF(MovableConvertible) v, insert_commit_data &data)
|
||||||
{
|
{
|
||||||
NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(v));
|
NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(v));
|
||||||
scoped_node_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
return iterator(this->icont().insert_unique_commit(*tmp, data));
|
||||||
iterator ret(this->icont().insert_unique_commit(*tmp, data));
|
|
||||||
destroy_deallocator.release();
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class MovableConvertible>
|
template<class MovableConvertible>
|
||||||
@@ -950,7 +963,8 @@ class hash_table
|
|||||||
//IOG temp
|
//IOG temp
|
||||||
BOOST_CONTAINER_FORCEINLINE iterator insert(const value_type& v)
|
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;
|
return this->insert_unique(v).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1005,7 +1019,7 @@ class hash_table
|
|||||||
return std::pair<iterator, bool>(iterator(ret.first), ret.second);
|
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));
|
BOOST_ASSERT(position != this->cend() && (priv_is_linked)(position));
|
||||||
return this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()));
|
return this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()));
|
||||||
@@ -1185,11 +1199,11 @@ class hash_table
|
|||||||
|
|
||||||
void reserve(size_type n)
|
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);
|
std::size_t sc = Icont::suggested_upper_bucket_count(n);
|
||||||
bucket_holder_t& this_buckets = *this;
|
bucket_holder_t& this_buckets = *this;
|
||||||
bucket_holder_t new_buckets(sc, this_buckets.get_allocator());
|
bucket_holder_t new_buckets(sc + Icont::bucket_overhead, this_buckets.get_allocator());
|
||||||
this->icont().rehash(bucket_traits(new_buckets.data(), sc));
|
this->icont().rehash(bucket_traits(new_buckets.data(), new_buckets.size()));
|
||||||
this_buckets.swap(new_buckets);
|
this_buckets.swap(new_buckets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -113,20 +113,31 @@ using tree_assoc_options_t = typename boost::container::tree_assoc_options<Optio
|
|||||||
|
|
||||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
template<bool StoreHash>
|
template<bool StoreHash, bool CacheBegin, bool LinearBuckets>
|
||||||
struct hash_opt
|
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)
|
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
//!This option setter specifies if node size is optimized
|
//!This option setter specifies if nodes also store the hash value
|
||||||
//!storing rebalancing data masked into pointers for ordered associative containers
|
//!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)
|
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
|
//! Helper metafunction to combine options into a single type to be used
|
||||||
//! by \c boost::container::hash_set, \c boost::container::hash_multiset
|
//! by \c boost::container::hash_set, \c boost::container::hash_multiset
|
||||||
//! \c boost::container::hash_map and \c boost::container::hash_multimap.
|
//! \c boost::container::hash_map and \c boost::container::hash_multimap.
|
||||||
@@ -147,7 +158,10 @@ struct hash_assoc_options
|
|||||||
Options...
|
Options...
|
||||||
#endif
|
#endif
|
||||||
>::type packed_options;
|
>::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
|
/// @endcond
|
||||||
typedef implementation_defined type;
|
typedef implementation_defined type;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user