forked from boostorg/intrusive
Add experimental fastmod_buckets option
This commit is contained in:
@ -201,16 +201,12 @@ class hashtable_iterator
|
||||
BOOST_INTRUSIVE_FORCEINLINE const value_traits &priv_value_traits() const
|
||||
{ return traitsptr_->priv_value_traits(); }
|
||||
|
||||
BOOST_INTRUSIVE_FORCEINLINE const bucket_traits &priv_bucket_traits() const
|
||||
{ return traitsptr_->priv_bucket_traits(); }
|
||||
|
||||
private:
|
||||
|
||||
void increment()
|
||||
{
|
||||
const bucket_traits &rbuck_traits = this->priv_bucket_traits();
|
||||
bucket_type* const buckets = boost::movelib::to_raw_pointer(rbuck_traits.bucket_begin());
|
||||
const std::size_t buckets_len = rbuck_traits.bucket_count();
|
||||
bucket_type* const buckets = boost::movelib::to_raw_pointer(traitsptr_->priv_bucket_traits().bucket_begin());
|
||||
const std::size_t buckets_len = traitsptr_->priv_bucket_traits().bucket_count();
|
||||
|
||||
++slist_it_;
|
||||
const slist_node_ptr n = slist_it_.pointed_node();
|
||||
@ -334,7 +330,7 @@ class hashtable_iterator<BucketValueTraits, true, IsConst>
|
||||
{ return i.slist_it_ == i2.slist_it_; }
|
||||
|
||||
BOOST_INTRUSIVE_FORCEINLINE friend bool operator!= (const hashtable_iterator& i, const hashtable_iterator& i2)
|
||||
{ return !(i == i2); }
|
||||
{ return i.slist_it_ != i2.slist_it_; }
|
||||
|
||||
BOOST_INTRUSIVE_FORCEINLINE reference operator*() const
|
||||
{ return *this->operator ->(); }
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -212,13 +212,22 @@ BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash)
|
||||
//!with the same key.
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_multikey, bool, Enabled, optimize_multikey)
|
||||
|
||||
//!This option setter specifies if the bucket array will be always power of two.
|
||||
//!This option setter specifies if the length of the bucket array provided by
|
||||
//!the user will always be power of two.
|
||||
//!This allows using masks instead of the default modulo operation to determine
|
||||
//!the bucket number from the hash value, leading to better performance.
|
||||
//!In debug mode, if power of two buckets mode is activated, the bucket length
|
||||
//!will be checked with assertions.
|
||||
//!In debug mode, the provided bucket array length will be checked with assertions.
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(power_2_buckets, bool, Enabled, power_2_buckets)
|
||||
|
||||
//!WARNING: this option is EXPERIMENTAL, don't use it in production code
|
||||
//!This option setter specifies if the length of the bucket array provided by
|
||||
//!the user will always be a value specified by the
|
||||
//!suggested_upper|lower_bucket_count call. This allows the use of some
|
||||
//!precomputed values and speeds hash to bucket index operations, leading
|
||||
//!to better performance.
|
||||
//!In debug mode, the provided bucket array length will be checked with assertions.
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(fastmod_buckets, bool, Enabled, fastmod_buckets)
|
||||
|
||||
//!This option setter specifies if the container will cache a pointer to the first
|
||||
//!non-empty bucket so that begin() is always constant-time.
|
||||
//!This is specially helpful when we can have containers with a few elements
|
||||
|
@ -456,6 +456,7 @@ struct make_unordered_set
|
||||
| (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
|
||||
| (std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
|
||||
| (std::size_t(packed_options::linear_buckets)*hash_bool_flags::linear_buckets_pos)
|
||||
| (std::size_t(packed_options::fastmod_buckets)*hash_bool_flags::fastmod_buckets_pos)
|
||||
> implementation_defined;
|
||||
|
||||
/// @endcond
|
||||
@ -910,6 +911,7 @@ struct make_unordered_multiset
|
||||
| (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
|
||||
| (std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
|
||||
| (std::size_t(packed_options::linear_buckets)*hash_bool_flags::linear_buckets_pos)
|
||||
| (std::size_t(packed_options::fastmod_buckets)*hash_bool_flags::fastmod_buckets_pos)
|
||||
> implementation_defined;
|
||||
|
||||
/// @endcond
|
||||
|
@ -243,24 +243,27 @@ void test_common_unordered_and_associative_container(Container & c, Data & d, bo
|
||||
//If size_type is big enough the upper bound is returned
|
||||
BOOST_IF_CONSTEXPR(sizeof(size_type) < sizeof(std::size_t)){
|
||||
sz = Container::suggested_upper_bucket_count(size_type(-1)/2);
|
||||
BOOST_TEST( sz >= size_type(-1)/2 );
|
||||
BOOST_TEST( sz > size_type(-1)/2 );
|
||||
}
|
||||
sz = Container::suggested_upper_bucket_count(size_type(-1)/4);
|
||||
BOOST_TEST( sz >= size_type(-1)/4 );
|
||||
BOOST_TEST( sz > size_type(-1)/4 );
|
||||
sz = Container::suggested_upper_bucket_count(size_type(-1) / 8);
|
||||
BOOST_TEST(sz >= size_type(-1) / 8);
|
||||
BOOST_TEST(sz > size_type(-1) / 8);
|
||||
sz = Container::suggested_upper_bucket_count(0);
|
||||
BOOST_TEST( sz > 0 );
|
||||
//
|
||||
//suggested_lower_bucket_count
|
||||
//
|
||||
sz = Container::suggested_lower_bucket_count(size_type(-1));
|
||||
BOOST_TEST( sz <= size_type(-1) );
|
||||
//If size_type is big enough the lower bound is returned
|
||||
BOOST_IF_CONSTEXPR(sizeof(size_type) < sizeof(std::size_t)) {
|
||||
sz = Container::suggested_lower_bucket_count(size_type(-1) / 2);
|
||||
BOOST_TEST(sz >= size_type(-1) / 2);
|
||||
}
|
||||
//In the rest of cases the lower bound is returned
|
||||
sz = Container::suggested_lower_bucket_count(size_type(-1)/2);
|
||||
BOOST_TEST( sz <= size_type(-1)/2 );
|
||||
sz = Container::suggested_lower_bucket_count(size_type(-1)/4);
|
||||
BOOST_TEST( sz <= size_type(-1)/4 );
|
||||
BOOST_TEST( sz >= size_type(-1)/4 );
|
||||
sz = Container::suggested_lower_bucket_count(size_type(-1) / 8);
|
||||
BOOST_TEST(sz >= size_type(-1) / 8);
|
||||
//Minimum fallbacks to the lowest possible value
|
||||
sz = Container::suggested_upper_bucket_count(0);
|
||||
BOOST_TEST( sz > 0 );
|
||||
|
@ -28,7 +28,7 @@
|
||||
using namespace boost::intrusive;
|
||||
|
||||
template < class ValueTraits, bool ConstantTimeSize, bool CacheBegin, bool CompareHash
|
||||
, bool Incremental, bool Map, bool DefaultHolder, bool LinearBuckets>
|
||||
, bool Incremental, bool Map, bool DefaultHolder, bool LinearBuckets, bool FastMod>
|
||||
struct rebinder
|
||||
{
|
||||
typedef unordered_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
|
||||
@ -47,6 +47,7 @@ struct rebinder
|
||||
, compare_hash<CompareHash>
|
||||
, incremental<Incremental>
|
||||
, linear_buckets<LinearBuckets>
|
||||
// , fastmod_buckets<FastMod>
|
||||
, typename common_t::holder_opt
|
||||
, typename common_t::key_of_value_opt
|
||||
, Option1
|
||||
@ -90,7 +91,8 @@ class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Base
|
||||
test::test_unordered
|
||||
< //cache_begin, compare_hash, incremental
|
||||
rebinder< base_hook_t, ConstantTimeSize, ConstantTimeSize
|
||||
, !ConstantTimeSize, !!ConstantTimeSize, Map, DefaultHolder, LinearBuckets>
|
||||
, !ConstantTimeSize, !!ConstantTimeSize, Map, DefaultHolder
|
||||
, LinearBuckets, LinearBuckets && !ConstantTimeSize>
|
||||
>::test_all(data);
|
||||
}
|
||||
};
|
||||
@ -118,7 +120,8 @@ class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Memb
|
||||
test::test_unordered
|
||||
< //cache_begin, compare_hash, incremental
|
||||
rebinder <member_hook_t, ConstantTimeSize, false
|
||||
, !ConstantTimeSize, false, !ConstantTimeSize, DefaultHolder, LinearBuckets>
|
||||
, !ConstantTimeSize, false, !ConstantTimeSize, DefaultHolder
|
||||
, LinearBuckets, LinearBuckets && !ConstantTimeSize>
|
||||
>::test_all(data);
|
||||
}
|
||||
};
|
||||
@ -142,7 +145,8 @@ class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, NonM
|
||||
test::test_unordered
|
||||
< //cache_begin, compare_hash, incremental
|
||||
rebinder< typename testval_traits_t::nonhook_value_traits
|
||||
, ConstantTimeSize, false, false, false, Map, DefaultHolder, LinearBuckets>
|
||||
, ConstantTimeSize, false, false, false, Map, DefaultHolder
|
||||
, LinearBuckets, LinearBuckets && !ConstantTimeSize>
|
||||
>::test_all(data);
|
||||
}
|
||||
};
|
||||
@ -160,6 +164,7 @@ int main()
|
||||
test_main_template<void*, false, true, false, Member, true>::execute();
|
||||
test_main_template<void*, true, false, false, NonMember, true>::execute();
|
||||
test_main_template<void*, true, true, false, Base, true>::execute();
|
||||
test_main_template<void*, false, true, false, Base, true>::execute();
|
||||
|
||||
//smart_ptr
|
||||
test_main_template<smart_ptr<void>, false, false, false, Member, false>::execute();
|
||||
|
Reference in New Issue
Block a user