Add mix32_policy

This commit is contained in:
Peter Dimov
2022-01-18 21:31:53 +02:00
parent 98494420c5
commit bf86730a62
2 changed files with 63 additions and 0 deletions

View File

@ -2035,6 +2035,45 @@ namespace boost {
}
};
template <typename SizeT> struct mix32_policy
{
template <typename Hash, typename T>
static inline SizeT apply_hash(Hash const& hf, T const& x)
{
SizeT key = hf(x);
// "Integer Hash Function", Thomas Wang, 1997
// https://gist.github.com/badboy/6267743
// http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm
key = ~key + (key << 15); // key = (key << 15) - key - 1;
key = key ^ (key >> 12);
key = key + (key << 2);
key = key ^ (key >> 4);
key = key * 2057; // key = (key + (key << 3)) + (key << 11);
key = key ^ (key >> 16);
return key;
}
static inline SizeT to_bucket(SizeT bucket_count, SizeT hash)
{
BOOST_ASSERT( boost::core::has_single_bit( bucket_count ) );
return hash & (bucket_count - 1);
}
static inline SizeT new_bucket_count(SizeT min)
{
if (min <= 4)
return 4;
return boost::core::bit_ceil(min);
}
static inline SizeT prev_bucket_count(SizeT max)
{
return boost::core::bit_floor(max);
}
};
template <int digits, int radix> struct pick_policy_impl
{
typedef prime_policy<std::size_t> type;
@ -2045,6 +2084,11 @@ namespace boost {
typedef mix64_policy<std::size_t> type;
};
template <> struct pick_policy_impl<32, 2>
{
typedef mix32_policy<std::size_t> type;
};
template <typename T>
struct pick_policy2
: pick_policy_impl<std::numeric_limits<std::size_t>::digits,

View File

@ -42,5 +42,24 @@ int main()
}
}
{
typedef boost::uint32_t SizeT;
typedef boost::unordered::detail::mix32_policy<SizeT> policy;
for( SizeT i = 1; i < 200; ++i )
{
test<policy>( i );
}
for( int i = 8; i < 32; ++i )
{
SizeT x = SizeT( 1 ) << i;
test<policy>( x - 1 );
test<policy>( x );
test<policy>( x + 1 );
}
}
return boost::report_errors();
}