OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 // |
| 5 // This also contains public domain code from MurmurHash. From the |
| 6 // MurmurHash header: |
| 7 // |
| 8 // MurmurHash3 was written by Austin Appleby, and is placed in the public |
| 9 // domain. The author hereby disclaims copyright to this source code. |
| 10 |
| 11 #include "src/base/functional.h" |
| 12 |
| 13 #include <limits> |
| 14 |
| 15 #include "src/base/bits.h" |
| 16 |
| 17 namespace v8 { |
| 18 namespace base { |
| 19 |
| 20 namespace { |
| 21 |
| 22 template <typename T> |
| 23 inline size_t hash_value_unsigned(T value) { |
| 24 const unsigned size_t_bits = std::numeric_limits<size_t>::digits; |
| 25 // ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1 |
| 26 const unsigned length = (std::numeric_limits<T>::digits - 1) / size_t_bits; |
| 27 size_t seed = 0; |
| 28 // Hopefully, this loop can be unrolled. |
| 29 for (unsigned i = length * size_t_bits; i > 0; i -= size_t_bits) { |
| 30 seed ^= static_cast<size_t>(value >> i) + (seed << 6) + (seed >> 2); |
| 31 } |
| 32 seed ^= static_cast<size_t>(value) + (seed << 6) + (seed >> 2); |
| 33 return seed; |
| 34 } |
| 35 |
| 36 } // namespace |
| 37 |
| 38 |
| 39 // This code was taken from MurmurHash. |
| 40 size_t hash_combine(size_t seed, size_t value) { |
| 41 #if V8_HOST_ARCH_32_BIT |
| 42 const uint32_t c1 = 0xcc9e2d51; |
| 43 const uint32_t c2 = 0x1b873593; |
| 44 |
| 45 value *= c1; |
| 46 value = bits::RotateRight32(value, 15); |
| 47 value *= c2; |
| 48 |
| 49 seed ^= value; |
| 50 seed = bits::RotateRight32(seed, 13); |
| 51 seed = seed * 5 + 0xe6546b64; |
| 52 #else |
| 53 const uint64_t m = V8_UINT64_C(0xc6a4a7935bd1e995); |
| 54 const uint32_t r = 47; |
| 55 |
| 56 value *= m; |
| 57 value ^= value >> r; |
| 58 value *= m; |
| 59 |
| 60 seed ^= value; |
| 61 seed *= m; |
| 62 #endif // V8_HOST_ARCH_32_BIT |
| 63 return seed; |
| 64 } |
| 65 |
| 66 |
| 67 size_t hash_value(unsigned long v) { // NOLINT(runtime/int) |
| 68 return hash_value_unsigned(v); |
| 69 } |
| 70 |
| 71 |
| 72 size_t hash_value(unsigned long long v) { // NOLINT(runtime/int) |
| 73 return hash_value_unsigned(v); |
| 74 } |
| 75 |
| 76 |
| 77 size_t hash_value(float v) { |
| 78 // 0 and -0 both hash to zero. |
| 79 return v != 0.0f ? hash_value(bit_cast<uint32_t>(v)) : 0; |
| 80 } |
| 81 |
| 82 |
| 83 size_t hash_value(double v) { |
| 84 // 0 and -0 both hash to zero. |
| 85 return v != 0.0 ? hash_value(bit_cast<uint64_t>(v)) : 0; |
| 86 } |
| 87 |
| 88 } // namespace base |
| 89 } // namespace v8 |
OLD | NEW |