utils.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package xxh3
  2. import (
  3. "math/bits"
  4. "unsafe"
  5. )
  6. // Uint128 is a 128 bit value.
  7. // The actual value can be thought of as u.Hi<<64 | u.Lo.
  8. type Uint128 struct {
  9. Hi, Lo uint64
  10. }
  11. // Bytes returns the uint128 as an array of bytes in canonical form (big-endian encoded).
  12. func (u Uint128) Bytes() [16]byte {
  13. return [16]byte{
  14. byte(u.Hi >> 0x38), byte(u.Hi >> 0x30), byte(u.Hi >> 0x28), byte(u.Hi >> 0x20),
  15. byte(u.Hi >> 0x18), byte(u.Hi >> 0x10), byte(u.Hi >> 0x08), byte(u.Hi),
  16. byte(u.Lo >> 0x38), byte(u.Lo >> 0x30), byte(u.Lo >> 0x28), byte(u.Lo >> 0x20),
  17. byte(u.Lo >> 0x18), byte(u.Lo >> 0x10), byte(u.Lo >> 0x08), byte(u.Lo),
  18. }
  19. }
  20. type (
  21. ptr = unsafe.Pointer
  22. ui = uintptr
  23. u8 = uint8
  24. u32 = uint32
  25. u64 = uint64
  26. u128 = Uint128
  27. )
  28. type str struct {
  29. p ptr
  30. l uint
  31. }
  32. func readU8(p ptr, o ui) uint8 {
  33. return *(*uint8)(ptr(ui(p) + o))
  34. }
  35. func readU16(p ptr, o ui) uint16 {
  36. b := (*[2]byte)(ptr(ui(p) + o))
  37. return uint16(b[0]) | uint16(b[1])<<8
  38. }
  39. func readU32(p ptr, o ui) uint32 {
  40. b := (*[4]byte)(ptr(ui(p) + o))
  41. return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
  42. }
  43. func readU64(p ptr, o ui) uint64 {
  44. b := (*[8]byte)(ptr(ui(p) + o))
  45. return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
  46. uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
  47. }
  48. func writeU64(p ptr, o ui, v u64) {
  49. b := (*[8]byte)(ptr(ui(p) + o))
  50. b[0] = byte(v)
  51. b[1] = byte(v >> 8)
  52. b[2] = byte(v >> 16)
  53. b[3] = byte(v >> 24)
  54. b[4] = byte(v >> 32)
  55. b[5] = byte(v >> 40)
  56. b[6] = byte(v >> 48)
  57. b[7] = byte(v >> 56)
  58. }
  59. const secretSize = 192
  60. func initSecret(secret ptr, seed u64) {
  61. for i := ui(0); i < secretSize/16; i++ {
  62. lo := readU64(key, 16*i) + seed
  63. hi := readU64(key, 16*i+8) - seed
  64. writeU64(secret, 16*i, lo)
  65. writeU64(secret, 16*i+8, hi)
  66. }
  67. }
  68. func xxh64AvalancheSmall(x u64) u64 {
  69. // x ^= x >> 33 // x must be < 32 bits
  70. // x ^= u64(key32_000 ^ key32_004) // caller must do this
  71. x *= prime64_2
  72. x ^= x >> 29
  73. x *= prime64_3
  74. x ^= x >> 32
  75. return x
  76. }
  77. func xxhAvalancheSmall(x u64) u64 {
  78. x ^= x >> 33
  79. x *= prime64_2
  80. x ^= x >> 29
  81. x *= prime64_3
  82. x ^= x >> 32
  83. return x
  84. }
  85. func xxh64AvalancheFull(x u64) u64 {
  86. x ^= x >> 33
  87. x *= prime64_2
  88. x ^= x >> 29
  89. x *= prime64_3
  90. x ^= x >> 32
  91. return x
  92. }
  93. func xxh3Avalanche(x u64) u64 {
  94. x ^= x >> 37
  95. x *= 0x165667919e3779f9
  96. x ^= x >> 32
  97. return x
  98. }
  99. func rrmxmx(h64 u64, len u64) u64 {
  100. h64 ^= bits.RotateLeft64(h64, 49) ^ bits.RotateLeft64(h64, 24)
  101. h64 *= 0x9fb21c651e98df25
  102. h64 ^= (h64 >> 35) + len
  103. h64 *= 0x9fb21c651e98df25
  104. h64 ^= (h64 >> 28)
  105. return h64
  106. }
  107. func mulFold64(x, y u64) u64 {
  108. hi, lo := bits.Mul64(x, y)
  109. return hi ^ lo
  110. }