github.com/flower-corp/rosedb@v1.1.2-0.20230117132829-21dc4f7b319a/util/hash.go (about)

     1  package util
     2  
     3  import "unsafe"
     4  
     5  //go:linkname runtimeMemhash runtime.memhash
     6  //go:noescape
     7  func runtimeMemhash(p unsafe.Pointer, seed, s uintptr) uintptr
     8  
     9  // MemHash is the hash function used by go map, it utilizes available hardware instructions(behaves
    10  // as aeshash if aes instruction is available).
    11  // NOTE: The hash seed changes for every process. So, this cannot be used as a persistent hash.
    12  func MemHash(buf []byte) uint64 {
    13  	return rthash(buf, 923)
    14  }
    15  
    16  func rthash(b []byte, seed uint64) uint64 {
    17  	if len(b) == 0 {
    18  		return seed
    19  	}
    20  	// The runtime hasher only works on uintptr. For 64-bit
    21  	// architectures, we use the hasher directly. Otherwise,
    22  	// we use two parallel hashers on the lower and upper 32 bits.
    23  	if unsafe.Sizeof(uintptr(0)) == 8 {
    24  		return uint64(runtimeMemhash(unsafe.Pointer(&b[0]), uintptr(seed), uintptr(len(b))))
    25  	}
    26  	lo := runtimeMemhash(unsafe.Pointer(&b[0]), uintptr(seed), uintptr(len(b)))
    27  	hi := runtimeMemhash(unsafe.Pointer(&b[0]), uintptr(seed>>32), uintptr(len(b)))
    28  	return uint64(hi)<<32 | uint64(lo)
    29  }