Revision: 24420
Author:   [email protected]
Date:     Mon Oct  6 15:23:59 2014 UTC
Log:      Don't use identity as hash function for integers.

Also slightly improve hashing of floats/doubles.

TEST=unittests
[email protected]

Review URL: https://codereview.chromium.org/632713002
https://code.google.com/p/v8/source/detail?r=24420

Modified:
 /branches/bleeding_edge/src/base/functional.cc
 /branches/bleeding_edge/src/base/functional.h
 /branches/bleeding_edge/test/unittests/base/functional-unittest.cc

=======================================
--- /branches/bleeding_edge/src/base/functional.cc Mon Oct 6 12:27:24 2014 UTC +++ /branches/bleeding_edge/src/base/functional.cc Mon Oct 6 15:23:59 2014 UTC
@@ -62,6 +62,19 @@
 #endif  // V8_HOST_ARCH_32_BIT
   return seed;
 }
+
+
+// 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)
@@ -76,13 +89,13 @@

 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
=======================================
--- /branches/bleeding_edge/src/base/functional.h Mon Oct 6 12:27:24 2014 UTC +++ /branches/bleeding_edge/src/base/functional.h Mon Oct 6 15:23:59 2014 UTC
@@ -76,11 +76,11 @@
 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) {        \
=======================================
--- /branches/bleeding_edge/test/unittests/base/functional-unittest.cc Mon Oct 6 12:27:24 2014 UTC +++ /branches/bleeding_edge/test/unittests/base/functional-unittest.cc Mon Oct 6 15:23:59 2014 UTC
@@ -83,7 +83,7 @@

 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.

Reply via email to