Kaynağa Gözat

Add 64-bit version of murmur2

Daniele Bartolini 12 yıl önce
ebeveyn
işleme
e81d4e2c67
1 değiştirilmiş dosya ile 56 ekleme ve 1 silme
  1. 56 1
      engine/core/strings/Hash.h

+ 56 - 1
engine/core/strings/Hash.h

@@ -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)