github.com/GitbookIO/syncgroup@v0.0.0-20200915204659-4f0b2961ab10/quickhash/strhash.go (about) 1 package quickhash 2 3 import ( 4 "reflect" 5 _ "runtime" 6 "unsafe" // required to use //go:linkname 7 ) 8 9 // Fixed seed for deterministic outcomes 10 const shSeed uint64 = 42 11 12 // Modified from runtime/alg.go 13 func rthash(ptr unsafe.Pointer, size int, seed uint64) uint64 { 14 if size == 0 { 15 return seed 16 } 17 // The runtime hasher only works on uintptr. For 64-bit 18 // architectures, we use the hasher directly. Otherwise, 19 // we use two parallel hashers on the lower and upper 32 bits. 20 if unsafe.Sizeof(uintptr(0)) == 8 { 21 return uint64(runtime_memhash(ptr, uintptr(seed), uintptr(size))) 22 } 23 lo := runtime_memhash(ptr, uintptr(seed), uintptr(size)) 24 hi := runtime_memhash(ptr, uintptr(seed>>32), uintptr(size)) 25 return uint64(hi)<<32 | uint64(lo) 26 } 27 28 //go:linkname runtime_memhash runtime.memhash 29 //go:noescape 30 func runtime_memhash(p unsafe.Pointer, seed, s uintptr) uintptr 31 32 func StrHash(str string) uint64 { 33 hdr := (*reflect.StringHeader)(unsafe.Pointer(&str)) 34 ptr := unsafe.Pointer(hdr.Data) 35 return uint64(rthash(ptr, len(str), shSeed)) 36 } 37 38 func ByteHash(data []byte) uint64 { 39 return uint64(rthash(unsafe.Pointer(&data[0]), len(data), shSeed)) 40 }