farmhashmk.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package farm
  2. func hash32Len5to12(s []byte, seed uint32) uint32 {
  3. slen := len(s)
  4. a := uint32(len(s))
  5. b := uint32(len(s) * 5)
  6. c := uint32(9)
  7. d := b + seed
  8. a += fetch32(s, 0)
  9. b += fetch32(s, slen-4)
  10. c += fetch32(s, ((slen >> 1) & 4))
  11. return fmix(seed ^ mur(c, mur(b, mur(a, d))))
  12. }
  13. // Hash32 hashes a byte slice and returns a uint32 hash value
  14. func Hash32(s []byte) uint32 {
  15. slen := len(s)
  16. if slen <= 24 {
  17. if slen <= 12 {
  18. if slen <= 4 {
  19. return hash32Len0to4(s, 0)
  20. }
  21. return hash32Len5to12(s, 0)
  22. }
  23. return hash32Len13to24Seed(s, 0)
  24. }
  25. // len > 24
  26. h := uint32(slen)
  27. g := c1 * uint32(slen)
  28. f := g
  29. a0 := rotate32(fetch32(s, slen-4)*c1, 17) * c2
  30. a1 := rotate32(fetch32(s, slen-8)*c1, 17) * c2
  31. a2 := rotate32(fetch32(s, slen-16)*c1, 17) * c2
  32. a3 := rotate32(fetch32(s, slen-12)*c1, 17) * c2
  33. a4 := rotate32(fetch32(s, slen-20)*c1, 17) * c2
  34. h ^= a0
  35. h = rotate32(h, 19)
  36. h = h*5 + 0xe6546b64
  37. h ^= a2
  38. h = rotate32(h, 19)
  39. h = h*5 + 0xe6546b64
  40. g ^= a1
  41. g = rotate32(g, 19)
  42. g = g*5 + 0xe6546b64
  43. g ^= a3
  44. g = rotate32(g, 19)
  45. g = g*5 + 0xe6546b64
  46. f += a4
  47. f = rotate32(f, 19) + 113
  48. iters := (slen - 1) / 20
  49. for {
  50. a := fetch32(s, 0)
  51. b := fetch32(s, 4)
  52. c := fetch32(s, 8)
  53. d := fetch32(s, 12)
  54. e := fetch32(s, 16)
  55. h += a
  56. g += b
  57. f += c
  58. h = mur(d, h) + e
  59. g = mur(c, g) + a
  60. f = mur(b+e*c1, f) + d
  61. f += g
  62. g += f
  63. s = s[20:]
  64. iters--
  65. if iters == 0 {
  66. break
  67. }
  68. }
  69. g = rotate32(g, 11) * c1
  70. g = rotate32(g, 17) * c1
  71. f = rotate32(f, 11) * c1
  72. f = rotate32(f, 17) * c1
  73. h = rotate32(h+g, 19)
  74. h = h*5 + 0xe6546b64
  75. h = rotate32(h, 17) * c1
  76. h = rotate32(h+f, 19)
  77. h = h*5 + 0xe6546b64
  78. h = rotate32(h, 17) * c1
  79. return h
  80. }
  81. // Hash32WithSeed hashes a byte slice and a uint32 seed and returns a uint32 hash value
  82. func Hash32WithSeed(s []byte, seed uint32) uint32 {
  83. slen := len(s)
  84. if slen <= 24 {
  85. if slen >= 13 {
  86. return hash32Len13to24Seed(s, seed*c1)
  87. }
  88. if slen >= 5 {
  89. return hash32Len5to12(s, seed)
  90. }
  91. return hash32Len0to4(s, seed)
  92. }
  93. h := hash32Len13to24Seed(s[:24], seed^uint32(slen))
  94. return mur(Hash32(s[24:])+seed, h)
  95. }