attempt to fix murmur on big endian
[awesomized/libmemcached] / src / libhashkit / murmur3.cc
index 254b5090e3bf4d61450e4824d3be9bd692437949..4446a951ae74068159e9cb37b6d5d0f0186f9901 100644 (file)
@@ -39,6 +39,7 @@ static FORCE_INLINE uint64_t rotl64 ( uint64_t x, int8_t r )
 // Block read - if your platform needs to do endian-swapping or can only
 // handle aligned reads, do the conversion here
 
+#include <cassert>
 #include <cstring>
 template <typename T>
 static inline T getblock(const T *blocks, int i) {
@@ -96,13 +97,16 @@ void MurmurHash3_x86_32 ( const void * key, int len,
   for(i = -nblocks; i; i++)
   {
     uint32_t k1 = getblock(blocks,i);
+#if WORDS_BIGENDIAN
+    k1 = BYTESWAP_32(k1);
+#endif
 
     k1 *= c1;
     k1 = ROTL32(k1,15);
     k1 *= c2;
-    
+
     h1 ^= k1;
-    h1 = ROTL32(h1,13); 
+    h1 = ROTL32(h1,13);
     h1 = h1*5+0xe6546b64;
   }
 
@@ -112,16 +116,15 @@ void MurmurHash3_x86_32 ( const void * key, int len,
   const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
 
   uint32_t k1 = 0;
+  memcpy(&k1, tail, len & 3);
+#if WORDS_BIGENDIAN
+  k1 = BYTESWAP_32(k1);
+#endif
 
-  switch(len & 3)
-  {
-  case 3: k1 ^= tail[2] << 16;
-          /* fall through */
-  case 2: k1 ^= tail[1] << 8;
-          /* fall through */
-  case 1: k1 ^= tail[0];
-          k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
-  };
+  k1 *= c1;
+  k1 = ROTL32(k1,15);
+  k1 *= c2;
+  h1 ^= k1;
 
   //----------
   // finalization
@@ -131,7 +134,7 @@ void MurmurHash3_x86_32 ( const void * key, int len,
   h1 = fmix32(h1);
 
   *(uint32_t*)out = h1;
-} 
+}
 
 //-----------------------------------------------------------------------------
 
@@ -147,9 +150,9 @@ void MurmurHash3_x86_128 ( const void * key, const int len,
   uint32_t h3 = seed;
   uint32_t h4 = seed;
 
-  uint32_t c1 = 0x239b961b; 
+  uint32_t c1 = 0x239b961b;
   uint32_t c2 = 0xab0e9789;
-  uint32_t c3 = 0x38b34ae5; 
+  uint32_t c3 = 0x38b34ae5;
   uint32_t c4 = 0xa1e38b93;
 
   //----------