murmur.go 2.1 KB

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