attempt to fix murmur on big endian
authorMichael Wallner <mike@php.net>
Wed, 14 Oct 2020 09:25:23 +0000 (11:25 +0200)
committerMichael Wallner <mike@php.net>
Wed, 14 Oct 2020 09:25:23 +0000 (11:25 +0200)
src/libhashkit/murmur3.cc

index 0eda93199b0b71796bd6237e1f183f0fc0c090d3..4446a951ae74068159e9cb37b6d5d0f0186f9901 100644 (file)
@@ -44,24 +44,7 @@ static FORCE_INLINE uint64_t rotl64 ( uint64_t x, int8_t r )
 template <typename T>
 static inline T getblock(const T *blocks, int i) {
   T b;
-#if WORDS_BIGENDIAN
-  const uint8_t *data = ((const uint8_t *) blocks) + i * sizeof(T);
-# define sl(s) (((T)data[s - 1]) << (8 * (sizeof(T) - s)))
-  b = 0;
-  switch (sizeof(T)) {
-  case 8: b |= sl(8); /* fall through */
-  case 7: b |= sl(7); /* fall through */
-  case 6: b |= sl(6); /* fall through */
-  case 5: b |= sl(5); /* fall through */
-  case 4: b |= sl(4); /* fall through */
-  case 3: b |= sl(3); /* fall through */
-  case 2: b |= sl(2); /* fall through */
-  case 1: b |= sl(1); break;
-  default: assert(0);
-  }
-#else
   memcpy(&b, ((const uint8_t *) blocks) + i * sizeof(T), sizeof(T));
-#endif
   return b;
 }
 
@@ -114,6 +97,9 @@ 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);
@@ -130,24 +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;
-
-  switch(len & 3)
-  {
+  memcpy(&k1, tail, len & 3);
 #if WORDS_BIGENDIAN
-  case 3: k1 ^= tail[2] << 8;
-          /* fall through */
-  case 2: k1 ^= tail[1] << 16;
-          /* fall through */
-  case 1: k1 ^= tail[0] << 24;
-#else
-  case 3: k1 ^= tail[2] << 16;
-          /* fall through */
-  case 2: k1 ^= tail[1] << 8;
-          /* fall through */
-  case 1: k1 ^= tail[0];
+  k1 = BYTESWAP_32(k1);
 #endif
-          k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
-  };
+
+  k1 *= c1;
+  k1 = ROTL32(k1,15);
+  k1 *= c2;
+  h1 ^= k1;
 
   //----------
   // finalization