forked from boostorg/unordered
Add mix32_policy
This commit is contained in:
@ -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,
|
||||
|
@ -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();
|
||||
}
|
||||
|
Reference in New Issue
Block a user