murmurhash.cc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. /*
  7. Murmurhash from http://sites.google.com/site/murmurhash/
  8. All code is released to the public domain. For business purposes, Murmurhash
  9. is under the MIT license.
  10. */
  11. #include "murmurhash.h"
  12. #include "util/util.h"
  13. #if defined(__x86_64__)
  14. // -------------------------------------------------------------------
  15. //
  16. // The same caveats as 32-bit MurmurHash2 apply here - beware of alignment
  17. // and endian-ness issues if used across multiple platforms.
  18. //
  19. // 64-bit hash for 64-bit platforms
  20. #ifdef ROCKSDB_UBSAN_RUN
  21. #if defined(__clang__)
  22. __attribute__((__no_sanitize__("alignment")))
  23. #elif defined(__GNUC__)
  24. __attribute__((__no_sanitize_undefined__))
  25. #endif
  26. #endif
  27. uint64_t MurmurHash64A ( const void * key, int len, unsigned int seed )
  28. {
  29. const uint64_t m = 0xc6a4a7935bd1e995;
  30. const int r = 47;
  31. uint64_t h = seed ^ (len * m);
  32. const uint64_t * data = (const uint64_t *)key;
  33. const uint64_t * end = data + (len/8);
  34. while(data != end)
  35. {
  36. uint64_t k = *data++;
  37. k *= m;
  38. k ^= k >> r;
  39. k *= m;
  40. h ^= k;
  41. h *= m;
  42. }
  43. const unsigned char * data2 = (const unsigned char*)data;
  44. switch(len & 7)
  45. {
  46. case 7: h ^= ((uint64_t)data2[6]) << 48; FALLTHROUGH_INTENDED;
  47. case 6: h ^= ((uint64_t)data2[5]) << 40; FALLTHROUGH_INTENDED;
  48. case 5: h ^= ((uint64_t)data2[4]) << 32; FALLTHROUGH_INTENDED;
  49. case 4: h ^= ((uint64_t)data2[3]) << 24; FALLTHROUGH_INTENDED;
  50. case 3: h ^= ((uint64_t)data2[2]) << 16; FALLTHROUGH_INTENDED;
  51. case 2: h ^= ((uint64_t)data2[1]) << 8; FALLTHROUGH_INTENDED;
  52. case 1: h ^= ((uint64_t)data2[0]);
  53. h *= m;
  54. };
  55. h ^= h >> r;
  56. h *= m;
  57. h ^= h >> r;
  58. return h;
  59. }
  60. #elif defined(__i386__)
  61. // -------------------------------------------------------------------
  62. //
  63. // Note - This code makes a few assumptions about how your machine behaves -
  64. //
  65. // 1. We can read a 4-byte value from any address without crashing
  66. // 2. sizeof(int) == 4
  67. //
  68. // And it has a few limitations -
  69. //
  70. // 1. It will not work incrementally.
  71. // 2. It will not produce the same results on little-endian and big-endian
  72. // machines.
  73. unsigned int MurmurHash2 ( const void * key, int len, unsigned int seed )
  74. {
  75. // 'm' and 'r' are mixing constants generated offline.
  76. // They're not really 'magic', they just happen to work well.
  77. const unsigned int m = 0x5bd1e995;
  78. const int r = 24;
  79. // Initialize the hash to a 'random' value
  80. unsigned int h = seed ^ len;
  81. // Mix 4 bytes at a time into the hash
  82. const unsigned char * data = (const unsigned char *)key;
  83. while(len >= 4)
  84. {
  85. unsigned int k = *(unsigned int *)data;
  86. k *= m;
  87. k ^= k >> r;
  88. k *= m;
  89. h *= m;
  90. h ^= k;
  91. data += 4;
  92. len -= 4;
  93. }
  94. // Handle the last few bytes of the input array
  95. switch(len)
  96. {
  97. case 3: h ^= data[2] << 16; FALLTHROUGH_INTENDED;
  98. case 2: h ^= data[1] << 8; FALLTHROUGH_INTENDED;
  99. case 1: h ^= data[0];
  100. h *= m;
  101. };
  102. // Do a few final mixes of the hash to ensure the last few
  103. // bytes are well-incorporated.
  104. h ^= h >> 13;
  105. h *= m;
  106. h ^= h >> 15;
  107. return h;
  108. }
  109. #else
  110. // -------------------------------------------------------------------
  111. //
  112. // Same as MurmurHash2, but endian- and alignment-neutral.
  113. // Half the speed though, alas.
  114. unsigned int MurmurHashNeutral2 ( const void * key, int len, unsigned int seed )
  115. {
  116. const unsigned int m = 0x5bd1e995;
  117. const int r = 24;
  118. unsigned int h = seed ^ len;
  119. const unsigned char * data = (const unsigned char *)key;
  120. while(len >= 4)
  121. {
  122. unsigned int k;
  123. k = data[0];
  124. k |= data[1] << 8;
  125. k |= data[2] << 16;
  126. k |= data[3] << 24;
  127. k *= m;
  128. k ^= k >> r;
  129. k *= m;
  130. h *= m;
  131. h ^= k;
  132. data += 4;
  133. len -= 4;
  134. }
  135. switch(len)
  136. {
  137. case 3: h ^= data[2] << 16; FALLTHROUGH_INTENDED;
  138. case 2: h ^= data[1] << 8; FALLTHROUGH_INTENDED;
  139. case 1: h ^= data[0];
  140. h *= m;
  141. };
  142. h ^= h >> 13;
  143. h *= m;
  144. h ^= h >> 15;
  145. return h;
  146. }
  147. #endif