Reviewers: jarin,
Description:
Don't use identity as hash function for integers.
Also slightly improve hashing of floats/doubles.
TEST=unittests
[email protected]
Please review this at https://codereview.chromium.org/632713002/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+19, -6 lines):
M src/base/functional.h
M src/base/functional.cc
M test/unittests/base/functional-unittest.cc
Index: src/base/functional.cc
diff --git a/src/base/functional.cc b/src/base/functional.cc
index
c4a61adda2452f9203b2b88cf986a58f7f1fea36..4c0f3c8b2af3bf3f16a0286402d895dd9d8c20f9
100644
--- a/src/base/functional.cc
+++ b/src/base/functional.cc
@@ -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
Index: src/base/functional.h
diff --git a/src/base/functional.h b/src/base/functional.h
index
60f93ddad5dfbac1059c32d1f58cbac0402258ef..d815c7214226cfd2e45c002144dac486d39ab59f
100644
--- a/src/base/functional.h
+++ b/src/base/functional.h
@@ -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) { \
Index: test/unittests/base/functional-unittest.cc
diff --git a/test/unittests/base/functional-unittest.cc
b/test/unittests/base/functional-unittest.cc
index
e6f260f2b8da68d2f9cb10b71f958641f9c4628c..4015485a88d1d0dfb38ca50a424f09c0b4af69a7
100644
--- a/test/unittests/base/functional-unittest.cc
+++ b/test/unittests/base/functional-unittest.cc
@@ -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;
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.