Commit 88b3fb8e authored by Giuseppe Ottaviano's avatar Giuseppe Ottaviano Committed by Facebook Github Bot

Make hasher<float> avalanching

Summary: It currently only sets the lower 32 bits.

Reviewed By: nbronson, philippv

Differential Revision: D7216798

fbshipit-source-id: 090f6dba990eeb7f1a9cc56e8615161c11eea026
parent 5ca9b9dc
...@@ -401,22 +401,12 @@ struct float_hasher { ...@@ -401,22 +401,12 @@ struct float_hasher {
return 0; return 0;
} }
/* constexpr */ if (sizeof(F) <= 4) { uint64_t u64 = 0;
uint32_t u32 = 0; memcpy(&u64, &f, sizeof(F));
memcpy(&u32, &f, sizeof(F)); return static_cast<size_t>(hash::twang_mix64(u64));
return static_cast<size_t>(hash::jenkins_rev_mix32(u32));
} else {
uint64_t u64 = 0;
memcpy(&u64, &f, sizeof(F));
return static_cast<size_t>(hash::twang_mix64(u64));
}
} }
}; };
template <typename F>
using float_hasher_avalanches =
std::integral_constant<bool, sizeof(F) == 8 || sizeof(size_t) == 4>;
} // namespace detail } // namespace detail
template <class Key, class Enable = void> template <class Key, class Enable = void>
...@@ -467,10 +457,7 @@ struct IsAvalanchingHasher<hasher<T, E>, K> ...@@ -467,10 +457,7 @@ struct IsAvalanchingHasher<hasher<T, E>, K>
: std::conditional< : std::conditional<
std::is_enum<T>::value || std::is_integral<T>::value, std::is_enum<T>::value || std::is_integral<T>::value,
detail::integral_hasher_avalanches<T>, detail::integral_hasher_avalanches<T>,
typename std::conditional< std::is_floating_point<T>>::type {};
std::is_floating_point<T>::value,
detail::float_hasher_avalanches<T>,
std::false_type>::type>::type {};
template <typename K> template <typename K>
struct IsAvalanchingHasher<Hash, K> : IsAvalanchingHasher<hasher<K>, K> {}; struct IsAvalanchingHasher<Hash, K> : IsAvalanchingHasher<hasher<K>, K> {};
......
...@@ -597,7 +597,7 @@ static_assert( ...@@ -597,7 +597,7 @@ static_assert(
folly::IsAvalanchingHasher<folly::hasher<int64_t>, int64_t>::value, folly::IsAvalanchingHasher<folly::hasher<int64_t>, int64_t>::value,
""); "");
static_assert( static_assert(
!folly::IsAvalanchingHasher<folly::hasher<float>, float>::value, folly::IsAvalanchingHasher<folly::hasher<float>, float>::value,
""); "");
static_assert( static_assert(
folly::IsAvalanchingHasher<folly::hasher<double>, double>::value, folly::IsAvalanchingHasher<folly::hasher<double>, double>::value,
...@@ -736,6 +736,10 @@ TEST(Traits, follyHasherInt64Avalances) { ...@@ -736,6 +736,10 @@ TEST(Traits, follyHasherInt64Avalances) {
int64_t{0}, [](int64_t& v) { v++; }); int64_t{0}, [](int64_t& v) { v++; });
} }
TEST(Traits, follyHasherFloatAvalanches) {
verifyAvalanching<folly::hasher<float>>(0.0f, [](float& v) { v += 1; });
}
TEST(Traits, follyHasherDoubleAvalanches) { TEST(Traits, follyHasherDoubleAvalanches) {
verifyAvalanching<folly::hasher<double>>(0.0, [](double& v) { v += 1; }); verifyAvalanching<folly::hasher<double>>(0.0, [](double& v) { v += 1; });
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment