github.com/moontrade/nogc@v0.1.7/hash/wyhash.go (about) 1 package hash 2 3 import "math/bits" 4 5 ///////////////////////////////////////////////////////////////////////////////////////////////////////// 6 // WyHash 7 ///////////////////////////////////////////////////////////////////////////////////////////////////////// 8 const ( 9 wyp0 uint64 = 0xa0761d6478bd642f 10 wyp1 uint64 = 0xe7037ed1a0b428db 11 wyp2 uint64 = 0x8ebc6af09c88c6e3 12 wyp3 uint64 = 0x589965cc75374cc3 13 wyp4 uint64 = 0x1d8e4e27c47d124f 14 wyp5 uint64 = 0xeb44accab455d165 15 16 wyseed uint64 = 0xeb44accab455d165 17 //wyseed uint64 = 0xeb44accab455d16f 18 //wyseed uint64 = 0x8ebc6af09c88c6e3 19 ) 20 21 func wymum(A, B uint64) uint64 { 22 hi, lo := bits.Mul64(A, B) 23 return hi ^ lo 24 } 25 26 ////go:inline 27 //func wymum(x, y uint64) uint64 { 28 // const mask32 = 1<<32 - 1 29 // x0 := x & mask32 30 // x1 := x >> 32 31 // y0 := y & mask32 32 // y1 := y >> 32 33 // w0 := x0 * y0 34 // t := x1*y0 + w0>>32 35 // w1 := t & mask32 36 // w2 := t >> 32 37 // w1 += x0 * y1 38 // return (x1*y1 + w2 + w1>>32) ^ (x * y) 39 //} 40 41 func WyHash32(v uint32) uint32 { 42 return uint32(wymum(wymum(uint64(v)^wyseed^wyp0, uint64(v)^wyseed^wyp1)^wyseed, uint64(4)^wyp4)) 43 } 44 45 func WyHash64(v uint64) uint64 { 46 return wymum(wymum(v^wyseed^wyp0, v^wyseed^wyp1)^wyseed, 8^wyp4) 47 } 48 49 func wyr3(p []byte) uint64 { 50 k := len(p) 51 return (uint64(p[0]) << 16) | (uint64(p[k>>1]) << 8) | uint64(p[k-1]) 52 } 53 54 func wyr8mix(b []byte) uint64 { 55 return uint64(uint32(b[0])|uint32(b[1])<<8|uint32(b[2])<<16|uint32(b[3])<<24)<<32 | 56 uint64(uint32(b[4])|uint32(b[5])<<8|uint32(b[6])<<16|uint32(b[7])<<24) 57 } 58 59 func WyHash(key []byte, wyseed uint64) uint64 { 60 p := key 61 if len(p) == 0 { 62 return wyseed 63 } 64 switch { 65 case len(p) < 4: 66 return wymum(wymum(wyr3(p)^wyseed^wyp0, wyseed^wyp1)^wyseed, uint64(len(p))^wyp4) 67 case len(p) <= 8: 68 return wymum(wymum(uint64(toUint32LE(p[:4]))^wyseed^wyp0, uint64(toUint32LE(p[len(p)-4:len(p)-4+4]))^wyseed^wyp1)^wyseed, uint64(len(p))^wyp4) 69 case len(p) <= 16: 70 return wymum(wymum(wyr8mix(p)^wyseed^wyp0, wyr8mix(p[len(p)-8:])^wyseed^wyp1)^wyseed, uint64(len(p))^wyp4) 71 case len(p) <= 24: 72 return wymum(wymum(wyr8mix(p)^wyseed^wyp0, wyr8mix(p[8:])^wyseed^wyp1)^wymum(wyr8mix(p[len(key)-8:])^wyseed^wyp2, wyseed^wyp3), uint64(len(p))^wyp4) 73 case len(p) <= 32: 74 return wymum(wymum(wyr8mix(p)^wyseed^wyp0, wyr8mix(p[8:])^wyseed^wyp1)^wymum(wyr8mix(p[16:])^wyseed^wyp2, wyr8mix(p[len(key)-8:])^wyseed^wyp3), uint64(len(p))^wyp4) 75 } 76 77 see1 := wyseed 78 for len(p) > 256 { 79 wyseed = wymum(toUint64LE(p[:8])^wyseed^wyp0, toUint64LE(p[8:8+8])^wyseed^wyp1) ^ wymum(toUint64LE(p[16:16+8])^wyseed^wyp2, toUint64LE(p[24:24+8])^wyseed^wyp3) 80 see1 = wymum(toUint64LE(p[32:32+8])^see1^wyp1, toUint64LE(p[40:40+8])^see1^wyp2) ^ wymum(toUint64LE(p[48:48+8])^see1^wyp3, toUint64LE(p[56:56+8])^see1^wyp0) 81 wyseed = wymum(toUint64LE(p[64:64+8])^wyseed^wyp0, toUint64LE(p[72:72+8])^wyseed^wyp1) ^ wymum(toUint64LE(p[80:80+8])^wyseed^wyp2, toUint64LE(p[88:88+8])^wyseed^wyp3) 82 see1 = wymum(toUint64LE(p[96:96+8])^see1^wyp1, toUint64LE(p[104:104+8])^see1^wyp2) ^ wymum(toUint64LE(p[112:112+8])^see1^wyp3, toUint64LE(p[120:120+8])^see1^wyp0) 83 wyseed = wymum(toUint64LE(p[128:128+8])^wyseed^wyp0, toUint64LE(p[136:136+8])^wyseed^wyp1) ^ wymum(toUint64LE(p[144:144+8])^wyseed^wyp2, toUint64LE(p[152:152+8])^wyseed^wyp3) 84 see1 = wymum(toUint64LE(p[160:160+8])^see1^wyp1, toUint64LE(p[168:168+8])^see1^wyp2) ^ wymum(toUint64LE(p[176:176+8])^see1^wyp3, toUint64LE(p[184:184+8])^see1^wyp0) 85 wyseed = wymum(toUint64LE(p[192:192+8])^wyseed^wyp0, toUint64LE(p[200:200+8])^wyseed^wyp1) ^ wymum(toUint64LE(p[208:208+8])^wyseed^wyp2, toUint64LE(p[216:216+8])^wyseed^wyp3) 86 see1 = wymum(toUint64LE(p[224:224+8])^see1^wyp1, toUint64LE(p[232:232+8])^see1^wyp2) ^ wymum(toUint64LE(p[240:240+8])^see1^wyp3, toUint64LE(p[248:248+8])^see1^wyp0) 87 p = p[256:] 88 } 89 90 for len(p) > 32 { 91 wyseed = wymum(toUint64LE(p[:8])^wyseed^wyp0, toUint64LE(p[8:8+8])^wyseed^wyp1) 92 see1 = wymum(toUint64LE(p[16:16+8])^see1^wyp2, toUint64LE(p[24:24+8])^see1^wyp3) 93 p = p[32:] 94 } 95 96 switch { 97 case len(p) < 4: 98 wyseed = wymum(wyr3(p)^wyseed^wyp0, wyseed^wyp1) 99 case len(p) <= 8: 100 wyseed = wymum(uint64(toUint32LE(p[:4]))^wyseed^wyp0, uint64(toUint32LE(p[len(p)-4:len(p)-4+4]))^wyseed^wyp1) 101 case len(p) <= 16: 102 wyseed = wymum(wyr8mix(p)^wyseed^wyp0, wyr8mix(p[len(p)-8:])^wyseed^wyp1) 103 case len(p) <= 24: 104 wyseed = wymum(wyr8mix(p)^wyseed^wyp0, wyr8mix(p[8:])^wyseed^wyp1) 105 see1 = wymum(wyr8mix(p[len(p)-8:])^see1^wyp2, see1^wyp3) 106 default: 107 wyseed = wymum(wyr8mix(p)^wyseed^wyp0, wyr8mix(p[8:])^wyseed^wyp1) 108 see1 = wymum(wyr8mix(p[16:])^see1^wyp2, wyr8mix(p[len(p)-8:])^see1^wyp3) 109 110 } 111 return wymum(wyseed^see1, uint64(len(key))^wyp4) 112 }