From bf86730a6288c75c714ccc854e80159e526aee9c Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 18 Jan 2022 21:31:53 +0200 Subject: [PATCH] Add mix32_policy --- .../boost/unordered/detail/implementation.hpp | 44 +++++++++++++++++++ test/unordered/mix_policy.cpp | 19 ++++++++ 2 files changed, 63 insertions(+) diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index 2de4c9a8..d99debc8 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -2035,6 +2035,45 @@ namespace boost { } }; + template struct mix32_policy + { + template + 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 struct pick_policy_impl { typedef prime_policy type; @@ -2045,6 +2084,11 @@ namespace boost { typedef mix64_policy type; }; + template <> struct pick_policy_impl<32, 2> + { + typedef mix32_policy type; + }; + template struct pick_policy2 : pick_policy_impl::digits, diff --git a/test/unordered/mix_policy.cpp b/test/unordered/mix_policy.cpp index 87cd7b8c..15308a1f 100644 --- a/test/unordered/mix_policy.cpp +++ b/test/unordered/mix_policy.cpp @@ -42,5 +42,24 @@ int main() } } + { + typedef boost::uint32_t SizeT; + typedef boost::unordered::detail::mix32_policy policy; + + for( SizeT i = 1; i < 200; ++i ) + { + test( i ); + } + + for( int i = 8; i < 32; ++i ) + { + SizeT x = SizeT( 1 ) << i; + + test( x - 1 ); + test( x ); + test( x + 1 ); + } + } + return boost::report_errors(); }