farmhashmk.cc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include "common.h"
  2. namespace {
  3. #include "farmhashnt.cc"
  4. }
  5. namespace farmhashmk {
  6. #undef Fetch
  7. #define Fetch Fetch32
  8. #undef Rotate
  9. #define Rotate Rotate32
  10. #undef Bswap
  11. #define Bswap Bswap32
  12. STATIC_INLINE uint32_t Hash32Len13to24(const char *s, size_t len, uint32_t seed = 0) {
  13. uint32_t a = Fetch(s - 4 + (len >> 1));
  14. uint32_t b = Fetch(s + 4);
  15. uint32_t c = Fetch(s + len - 8);
  16. uint32_t d = Fetch(s + (len >> 1));
  17. uint32_t e = Fetch(s);
  18. uint32_t f = Fetch(s + len - 4);
  19. uint32_t h = d * c1 + len + seed;
  20. a = Rotate(a, 12) + f;
  21. h = Mur(c, h) + a;
  22. a = Rotate(a, 3) + c;
  23. h = Mur(e, h) + a;
  24. a = Rotate(a + f, 12) + d;
  25. h = Mur(b ^ seed, h) + a;
  26. return fmix(h);
  27. }
  28. STATIC_INLINE uint32_t Hash32Len0to4(const char *s, size_t len, uint32_t seed = 0) {
  29. uint32_t b = seed;
  30. uint32_t c = 9;
  31. for (size_t i = 0; i < len; i++) {
  32. signed char v = s[i];
  33. b = b * c1 + v;
  34. c ^= b;
  35. }
  36. return fmix(Mur(b, Mur(len, c)));
  37. }
  38. STATIC_INLINE uint32_t Hash32Len5to12(const char *s, size_t len, uint32_t seed = 0) {
  39. uint32_t a = len, b = len * 5, c = 9, d = b + seed;
  40. a += Fetch(s);
  41. b += Fetch(s + len - 4);
  42. c += Fetch(s + ((len >> 1) & 4));
  43. return fmix(seed ^ Mur(c, Mur(b, Mur(a, d))));
  44. }
  45. uint32_t Hash32(const char *s, size_t len) {
  46. if (len <= 24) {
  47. return len <= 12 ?
  48. (len <= 4 ? Hash32Len0to4(s, len) : Hash32Len5to12(s, len)) :
  49. Hash32Len13to24(s, len);
  50. }
  51. // len > 24
  52. uint32_t h = len, g = c1 * len, f = g;
  53. uint32_t a0 = Rotate(Fetch(s + len - 4) * c1, 17) * c2;
  54. uint32_t a1 = Rotate(Fetch(s + len - 8) * c1, 17) * c2;
  55. uint32_t a2 = Rotate(Fetch(s + len - 16) * c1, 17) * c2;
  56. uint32_t a3 = Rotate(Fetch(s + len - 12) * c1, 17) * c2;
  57. uint32_t a4 = Rotate(Fetch(s + len - 20) * c1, 17) * c2;
  58. h ^= a0;
  59. h = Rotate(h, 19);
  60. h = h * 5 + 0xe6546b64;
  61. h ^= a2;
  62. h = Rotate(h, 19);
  63. h = h * 5 + 0xe6546b64;
  64. g ^= a1;
  65. g = Rotate(g, 19);
  66. g = g * 5 + 0xe6546b64;
  67. g ^= a3;
  68. g = Rotate(g, 19);
  69. g = g * 5 + 0xe6546b64;
  70. f += a4;
  71. f = Rotate(f, 19) + 113;
  72. size_t iters = (len - 1) / 20;
  73. do {
  74. uint32_t a = Fetch(s);
  75. uint32_t b = Fetch(s + 4);
  76. uint32_t c = Fetch(s + 8);
  77. uint32_t d = Fetch(s + 12);
  78. uint32_t e = Fetch(s + 16);
  79. h += a;
  80. g += b;
  81. f += c;
  82. h = Mur(d, h) + e;
  83. g = Mur(c, g) + a;
  84. f = Mur(b + e * c1, f) + d;
  85. f += g;
  86. g += f;
  87. s += 20;
  88. } while (--iters != 0);
  89. g = Rotate(g, 11) * c1;
  90. g = Rotate(g, 17) * c1;
  91. f = Rotate(f, 11) * c1;
  92. f = Rotate(f, 17) * c1;
  93. h = Rotate(h + g, 19);
  94. h = h * 5 + 0xe6546b64;
  95. h = Rotate(h, 17) * c1;
  96. h = Rotate(h + f, 19);
  97. h = h * 5 + 0xe6546b64;
  98. h = Rotate(h, 17) * c1;
  99. return h;
  100. }
  101. uint32_t Hash32WithSeed(const char *s, size_t len, uint32_t seed) {
  102. if (len <= 24) {
  103. if (len >= 13) return Hash32Len13to24(s, len, seed * c1);
  104. else if (len >= 5) return Hash32Len5to12(s, len, seed);
  105. else return Hash32Len0to4(s, len, seed);
  106. }
  107. uint32_t h = Hash32Len13to24(s, 24, seed ^ len);
  108. return Mur(Hash32(s + 24, len - 24) + seed, h);
  109. }
  110. } // namespace farmhashmk