|
|
@@ -44,6 +44,7 @@ const uint64_t FNV1A_PRIME_64 = 1099511628211ull;
|
|
|
|
|
|
// Functions
|
|
|
uint32_t murmur2_32(const void* key, size_t len, uint32_t seed);
|
|
|
+uint64_t murmur2_64(const void* key, size_t len, unsigned int seed);
|
|
|
uint32_t fnv1a_32(const void* key, size_t len);
|
|
|
uint64_t fnv1a_64(const void* key, size_t len);
|
|
|
|
|
|
@@ -63,7 +64,7 @@ uint64_t fnv1a_64(const void* key, size_t len);
|
|
|
/// machines.
|
|
|
inline uint32_t murmur2_32(const void* key, size_t len, uint32_t seed)
|
|
|
{
|
|
|
- CE_ASSERT(key != NULL, "Key must be != NULL");
|
|
|
+ CE_ASSERT_NOT_NULL(key);
|
|
|
|
|
|
// 'm' and 'r' are mixing constants generated offline.
|
|
|
// They're not really 'magic', they just happen to work well.
|
|
|
@@ -109,6 +110,60 @@ inline uint32_t murmur2_32(const void* key, size_t len, uint32_t seed)
|
|
|
return h;
|
|
|
}
|
|
|
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+inline uint64_t murmur2_64(const void* key, size_t len, unsigned int seed)
|
|
|
+{
|
|
|
+ CE_ASSERT_NOT_NULL(key);
|
|
|
+
|
|
|
+ const unsigned int m = 0x5bd1e995;
|
|
|
+ const int r = 24;
|
|
|
+
|
|
|
+ unsigned int h1 = seed ^ len;
|
|
|
+ unsigned int h2 = 0;
|
|
|
+
|
|
|
+ const unsigned int * data = (const unsigned int *)key;
|
|
|
+
|
|
|
+ while(len >= 8)
|
|
|
+ {
|
|
|
+ unsigned int k1 = *data++;
|
|
|
+ k1 *= m; k1 ^= k1 >> r; k1 *= m;
|
|
|
+ h1 *= m; h1 ^= k1;
|
|
|
+ len -= 4;
|
|
|
+
|
|
|
+ unsigned int k2 = *data++;
|
|
|
+ k2 *= m; k2 ^= k2 >> r; k2 *= m;
|
|
|
+ h2 *= m; h2 ^= k2;
|
|
|
+ len -= 4;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(len >= 4)
|
|
|
+ {
|
|
|
+ unsigned int k1 = *data++;
|
|
|
+ k1 *= m; k1 ^= k1 >> r; k1 *= m;
|
|
|
+ h1 *= m; h1 ^= k1;
|
|
|
+ len -= 4;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch(len)
|
|
|
+ {
|
|
|
+ case 3: h2 ^= ((unsigned char*)data)[2] << 16;
|
|
|
+ case 2: h2 ^= ((unsigned char*)data)[1] << 8;
|
|
|
+ case 1: h2 ^= ((unsigned char*)data)[0];
|
|
|
+ h2 *= m;
|
|
|
+ };
|
|
|
+
|
|
|
+ h1 ^= h2 >> 18; h1 *= m;
|
|
|
+ h2 ^= h1 >> 22; h2 *= m;
|
|
|
+ h1 ^= h2 >> 17; h1 *= m;
|
|
|
+ h2 ^= h1 >> 19; h2 *= m;
|
|
|
+
|
|
|
+ uint64_t h = h1;
|
|
|
+
|
|
|
+ h = (h << 32) | h2;
|
|
|
+
|
|
|
+ return h;
|
|
|
+}
|
|
|
+
|
|
|
//-----------------------------------------------------------------------------
|
|
|
/// FNV-1a hash, 32 bit
|
|
|
inline uint32_t fnv1a_32(const void* key, size_t len)
|