github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/core/utils/hash/murmurhash3.go (about) 1 package hash 2 3 import ( 4 "encoding/binary" 5 "unsafe" 6 ) 7 8 func Murmurhash3Onx8632(key []byte, seed uint32) uint32 { 9 const ( 10 ChunkSize = 4 11 C1 = 0xcc9e2d51 12 C2 = 0x1b872593 13 R1 = 15 14 R2 = 13 15 M = 5 16 N = 0xe6546b64 17 ) 18 hash := seed 19 keyLen := len(key) 20 nBlock := keyLen / ChunkSize 21 for i := 0; i < nBlock; i++ { 22 k := binary.LittleEndian.Uint32(key[i*ChunkSize : i*ChunkSize+ChunkSize]) 23 k = k * C1 24 k = (k << R1) | (k >> (32 - R1)) 25 k = k * C2 26 27 hash = hash ^ k 28 hash = (hash << R2) | (hash >> (32 - R2)) 29 hash = hash*M + N 30 } 31 if nBlock*ChunkSize == keyLen { 32 return hash 33 } 34 tail := (*[3]byte)(unsafe.Pointer(&key[nBlock*ChunkSize])) 35 var k1 uint32 36 switch keyLen & 3 { 37 case 3: 38 k1 ^= uint32(tail[2]) << 16 39 case 2: 40 k1 ^= uint32(tail[1]) << 8 41 case 1: 42 k1 ^= uint32(tail[0]) 43 k1 *= C1 44 k1 = (hash << R1) | (hash >> (32 - R1)) 45 k1 *= C2 46 hash ^= k1 47 } 48 hash = hash ^ uint32(keyLen) 49 hash = hash ^ (hash >> 16) 50 hash = hash * 0x85ebca6b 51 hash = hash ^ (hash >> 13) 52 hash = hash * 0xc2b2ae35 53 hash = hash ^ (hash >> 16) 54 return hash 55 } 56 57 func Murmurhash3Onx8632OnInt(key int64, seed uint32) uint32 { 58 keyArray := *(*[8]byte)(unsafe.Pointer(&key)) 59 return Murmurhash3Onx8632(keyArray[:], seed) 60 } 61 62 func Murmurhash3Onx8632OnUint(key uint64, seed uint32) uint32 { 63 return Murmurhash3Onx8632OnInt(int64(key), seed) 64 }