murmur.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package murmur
  2. const (
  3. c1 int64 = -8663945395140668459 // 0x87c37b91114253d5
  4. c2 int64 = 5545529020109919103 // 0x4cf5ad432745937f
  5. fmix1 int64 = -49064778989728563 // 0xff51afd7ed558ccd
  6. fmix2 int64 = -4265267296055464877 // 0xc4ceb9fe1a85ec53
  7. )
  8. func fmix(n int64) int64 {
  9. // cast to unsigned for logical right bitshift (to match C* MM3 implementation)
  10. n ^= int64(uint64(n) >> 33)
  11. n *= fmix1
  12. n ^= int64(uint64(n) >> 33)
  13. n *= fmix2
  14. n ^= int64(uint64(n) >> 33)
  15. return n
  16. }
  17. func block(p byte) int64 {
  18. return int64(int8(p))
  19. }
  20. func rotl(x int64, r uint8) int64 {
  21. // cast to unsigned for logical right bitshift (to match C* MM3 implementation)
  22. return (x << r) | (int64)((uint64(x) >> (64 - r)))
  23. }
  24. func Murmur3H1(data []byte) int64 {
  25. length := len(data)
  26. var h1, h2, k1, k2 int64
  27. // body
  28. nBlocks := length / 16
  29. for i := 0; i < nBlocks; i++ {
  30. k1, k2 = getBlock(data, i)
  31. k1 *= c1
  32. k1 = rotl(k1, 31)
  33. k1 *= c2
  34. h1 ^= k1
  35. h1 = rotl(h1, 27)
  36. h1 += h2
  37. h1 = h1*5 + 0x52dce729
  38. k2 *= c2
  39. k2 = rotl(k2, 33)
  40. k2 *= c1
  41. h2 ^= k2
  42. h2 = rotl(h2, 31)
  43. h2 += h1
  44. h2 = h2*5 + 0x38495ab5
  45. }
  46. // tail
  47. tail := data[nBlocks*16:]
  48. k1 = 0
  49. k2 = 0
  50. switch length & 15 {
  51. case 15:
  52. k2 ^= block(tail[14]) << 48
  53. fallthrough
  54. case 14:
  55. k2 ^= block(tail[13]) << 40
  56. fallthrough
  57. case 13:
  58. k2 ^= block(tail[12]) << 32
  59. fallthrough
  60. case 12:
  61. k2 ^= block(tail[11]) << 24
  62. fallthrough
  63. case 11:
  64. k2 ^= block(tail[10]) << 16
  65. fallthrough
  66. case 10:
  67. k2 ^= block(tail[9]) << 8
  68. fallthrough
  69. case 9:
  70. k2 ^= block(tail[8])
  71. k2 *= c2
  72. k2 = rotl(k2, 33)
  73. k2 *= c1
  74. h2 ^= k2
  75. fallthrough
  76. case 8:
  77. k1 ^= block(tail[7]) << 56
  78. fallthrough
  79. case 7:
  80. k1 ^= block(tail[6]) << 48
  81. fallthrough
  82. case 6:
  83. k1 ^= block(tail[5]) << 40
  84. fallthrough
  85. case 5:
  86. k1 ^= block(tail[4]) << 32
  87. fallthrough
  88. case 4:
  89. k1 ^= block(tail[3]) << 24
  90. fallthrough
  91. case 3:
  92. k1 ^= block(tail[2]) << 16
  93. fallthrough
  94. case 2:
  95. k1 ^= block(tail[1]) << 8
  96. fallthrough
  97. case 1:
  98. k1 ^= block(tail[0])
  99. k1 *= c1
  100. k1 = rotl(k1, 31)
  101. k1 *= c2
  102. h1 ^= k1
  103. }
  104. h1 ^= int64(length)
  105. h2 ^= int64(length)
  106. h1 += h2
  107. h2 += h1
  108. h1 = fmix(h1)
  109. h2 = fmix(h2)
  110. h1 += h2
  111. // the following is extraneous since h2 is discarded
  112. // h2 += h1
  113. return h1
  114. }