diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index f3e8dc39..27f2e330 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -2000,27 +2000,21 @@ namespace boost { 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 << 21); // key = (key << 21) - key - 1; - key = key ^ (key >> 24); - key = (key + (key << 3)) + (key << 8); // key * 265 - key = key ^ (key >> 14); - key = (key + (key << 2)) + (key << 4); // key * 21 - key = key ^ (key >> 28); - key = key + (key << 31); - return key; + // https://en.wikipedia.org/wiki/Hash_function#Fibonacci_hashing + SizeT const m = 11400714819323198485ull; // 2^64 / phi + return hf(x) * m; } static inline SizeT to_bucket(SizeT bucket_count, SizeT hash, int bcount_log2) { - BOOST_ASSERT( boost::core::has_single_bit( bucket_count ) ); BOOST_ASSERT( bucket_count == ( SizeT(1) << bcount_log2 ) ); - return hash & (bucket_count - 1); + (void)bucket_count; + + SizeT r = hash >> (64 - bcount_log2); + + BOOST_ASSERT( r < bucket_count ); + + return r; } static inline SizeT new_bucket_count(SizeT min)