Don't use identity as hash function for integers.
Also slightly improve hashing of floats/doubles. TEST=unittests R=jarin@chromium.org Review URL: https://codereview.chromium.org/632713002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24420 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
711218bc07
commit
03255440de
@ -64,6 +64,19 @@ size_t hash_combine(size_t seed, size_t value) {
|
||||
}
|
||||
|
||||
|
||||
// Thomas Wang, Integer Hash Functions.
|
||||
// http://www.concentric.net/~Ttwang/tech/inthash.htm
|
||||
size_t hash_value(unsigned int v) {
|
||||
v = ~v + (v << 15); // v = (v << 15) - v - 1;
|
||||
v = v ^ (v >> 12);
|
||||
v = v + (v << 2);
|
||||
v = v ^ (v >> 4);
|
||||
v = v * 2057; // v = (v + (v << 3)) + (v << 11);
|
||||
v = v ^ (v >> 16);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
size_t hash_value(unsigned long v) { // NOLINT(runtime/int)
|
||||
return hash_value_unsigned(v);
|
||||
}
|
||||
@ -76,13 +89,13 @@ size_t hash_value(unsigned long long v) { // NOLINT(runtime/int)
|
||||
|
||||
size_t hash_value(float v) {
|
||||
// 0 and -0 both hash to zero.
|
||||
return v != 0.0f ? hash_value(bit_cast<uint32_t>(v)) : 0;
|
||||
return v != 0.0f ? hash_value_unsigned(bit_cast<uint32_t>(v)) : 0;
|
||||
}
|
||||
|
||||
|
||||
size_t hash_value(double v) {
|
||||
// 0 and -0 both hash to zero.
|
||||
return v != 0.0 ? hash_value(bit_cast<uint64_t>(v)) : 0;
|
||||
return v != 0.0 ? hash_value_unsigned(bit_cast<uint64_t>(v)) : 0;
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
@ -76,11 +76,11 @@ inline size_t hash_combine(T const& v, Ts const&... vs) {
|
||||
V8_BASE_HASH_VALUE_TRIVIAL(bool)
|
||||
V8_BASE_HASH_VALUE_TRIVIAL(unsigned char)
|
||||
V8_BASE_HASH_VALUE_TRIVIAL(unsigned short) // NOLINT(runtime/int)
|
||||
V8_BASE_HASH_VALUE_TRIVIAL(unsigned int)
|
||||
#undef V8_BASE_HASH_VALUE_TRIVIAL
|
||||
|
||||
size_t hash_value(unsigned long v); // NOLINT(runtime/int)
|
||||
size_t hash_value(unsigned long long v); // NOLINT(runtime/int)
|
||||
size_t hash_value(unsigned int);
|
||||
size_t hash_value(unsigned long); // NOLINT(runtime/int)
|
||||
size_t hash_value(unsigned long long); // NOLINT(runtime/int)
|
||||
|
||||
#define V8_BASE_HASH_VALUE_SIGNED(type) \
|
||||
inline size_t hash_value(signed type v) { \
|
||||
|
@ -83,7 +83,7 @@ TYPED_TEST(FunctionalTest, HashIsStateless) {
|
||||
|
||||
TYPED_TEST(FunctionalTest, HashIsOkish) {
|
||||
const size_t kValues = 128;
|
||||
const size_t kMinHashes = kValues / (sizeof(uint64_t) / sizeof(size_t));
|
||||
const size_t kMinHashes = kValues / 4;
|
||||
std::set<TypeParam> vs;
|
||||
while (vs.size() != kValues) {
|
||||
TypeParam v;
|
||||
|
Loading…
Reference in New Issue
Block a user