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

index 4ff0f7c65f58a5e82feeb1c21a2c6f39d9d7d7f2..c1451639c57a67a069683892e4f5972f24f1262c 100644 (file)
 
 #ifdef HAVE_MURMUR_HASH
 
+#ifdef BYTESWAP_HEADER
+# include BYTESWAP_HEADER
+#endif
+
 #include <cstring>
 
 uint32_t hashkit_murmur(const char *key, size_t length, void *context)
@@ -82,14 +86,9 @@ uint32_t hashkit_murmur(const char *key, size_t length, void *context)
   while(length >= 4)
   {
     uint32_t k;
-#if WORDS_BIGENDIAN
-    k = (data[0]<<24)
-      | (data[1]<<16)
-      | (data[2]<<8)
-      | (data[3])
-    ;
-#else
     memcpy(&k, data, sizeof(k));
+#if WORDS_BIGENDIAN
+    k = BYTESWAP_32(k);
 #endif
 
     k *= m;
@@ -104,21 +103,15 @@ uint32_t hashkit_murmur(const char *key, size_t length, void *context)
   }
 
   // Handle the last few bytes of the input array
-
-  switch(length)
-  {
+  if (length) {
+    uint32_t k = 0;
+    memcpy(&k, data, length);
 #if WORDS_BIGENDIAN
-  case 3: h ^= ((uint32_t)data[2]) << 8;     /* fall through */
-  case 2: h ^= ((uint32_t)data[1]) << 16;    /* fall through */
-  case 1: h ^= ((uint32_t)data[0]) << 24;
-#else
-  case 3: h ^= ((uint32_t)data[2]) << 16;   /* fall through */
-  case 2: h ^= ((uint32_t)data[1]) << 8;    /* fall through */
-  case 1: h ^= data[0];
+    k = BYTESWAP_32(k);
 #endif
-          h *= m;
-  default: break;
-  };
+    h ^= k;
+    h *= m;
+  }
 
   /*
     Do a few final mixes of the hash to ensure the last few bytes are
index f761ade06494142f9197d81606f9f0f0150735c6..2048e991b87bb3d6b004520783b7f01dc4317952 100644 (file)
@@ -12,6 +12,7 @@
 
 #cmakedefine HAVE_ABI____CXA_DEMANGLE 1
 #cmakedefine HAVE_BACKTRACE 1
+#cmakedefine HAVE_BYTESWAP 1
 #cmakedefine HAVE_ALLOCA_H 1
 #cmakedefine HAVE_ARPA_INET_H 1
 #cmakedefine HAVE_DLFCN_H 1
@@ -74,4 +75,9 @@
 # define BACKTRACE_HEADER <@Backtrace_HEADER@>
 #endif
 
+#if HAVE_BYTESWAP
+# define BYTESWAP_32 @BYTESWAP_32@
+# cmakedefine BYTESWAP_HEADER <@BYTESWAP_HEADER@>
+#endif
+
 #define HAVE_LIBMEMCACHED 1