github.com/fufuok/utils@v1.0.10/xsync/util_hash.go (about) 1 package xsync 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 // makeSeed creates a random seed. 9 func makeSeed() uint64 { 10 var s1 uint32 11 for { 12 s1 = runtime_fastrand() 13 // We use seed 0 to indicate an uninitialized seed/hash, 14 // so keep trying until we get a non-zero seed. 15 if s1 != 0 { 16 break 17 } 18 } 19 s2 := runtime_fastrand() 20 return uint64(s1)<<32 | uint64(s2) 21 } 22 23 // hashString calculates a hash of s with the given seed. 24 func hashString(s string, seed uint64) uint64 { 25 if s == "" { 26 return seed 27 } 28 strh := (*reflect.StringHeader)(unsafe.Pointer(&s)) 29 return uint64(runtime_memhash(unsafe.Pointer(strh.Data), uintptr(seed), uintptr(strh.Len))) 30 } 31 32 //go:noescape 33 //go:linkname runtime_memhash runtime.memhash 34 func runtime_memhash(p unsafe.Pointer, h, s uintptr) uintptr 35 36 // how interface is represented in memory 37 type iface struct { 38 typ uintptr 39 word unsafe.Pointer 40 } 41 42 // same as runtime_typehash, but always returns a uint64 43 // see: maphash.rthash function for details 44 func runtime_typehash64(t uintptr, p unsafe.Pointer, seed uint64) uint64 { 45 if unsafe.Sizeof(uintptr(0)) == 8 { 46 return uint64(runtime_typehash(t, p, uintptr(seed))) 47 } 48 49 lo := runtime_typehash(t, p, uintptr(seed)) 50 hi := runtime_typehash(t, p, uintptr(seed>>32)) 51 return uint64(hi)<<32 | uint64(lo) 52 } 53 54 //go:noescape 55 //go:linkname runtime_typehash runtime.typehash 56 func runtime_typehash(t uintptr, p unsafe.Pointer, h uintptr) uintptr