github.com/segmentio/parquet-go@v0.0.0-20230712180008-5d42db8f0d47/hashprobe/wyhash/wyhash.go (about)

     1  // Package wyhash implements a hashing algorithm derived from the Go runtime's
     2  // internal hashing fallback, which uses a variation of the wyhash algorithm.
     3  package wyhash
     4  
     5  import (
     6  	"encoding/binary"
     7  	"math/bits"
     8  
     9  	"github.com/segmentio/parquet-go/sparse"
    10  )
    11  
    12  const (
    13  	m1 = 0xa0761d6478bd642f
    14  	m2 = 0xe7037ed1a0b428db
    15  	m3 = 0x8ebc6af09c88c6e3
    16  	m4 = 0x589965cc75374cc3
    17  	m5 = 0x1d8e4e27c47d124f
    18  )
    19  
    20  func mix(a, b uint64) uint64 {
    21  	hi, lo := bits.Mul64(a, b)
    22  	return hi ^ lo
    23  }
    24  
    25  func Hash32(value uint32, seed uintptr) uintptr {
    26  	return uintptr(mix(m5^4, mix(uint64(value)^m2, uint64(value)^uint64(seed)^m1)))
    27  }
    28  
    29  func Hash64(value uint64, seed uintptr) uintptr {
    30  	return uintptr(mix(m5^8, mix(value^m2, value^uint64(seed)^m1)))
    31  }
    32  
    33  func Hash128(value [16]byte, seed uintptr) uintptr {
    34  	a := binary.LittleEndian.Uint64(value[:8])
    35  	b := binary.LittleEndian.Uint64(value[8:])
    36  	return uintptr(mix(m5^16, mix(a^m2, b^uint64(seed)^m1)))
    37  }
    38  
    39  func MultiHash32(hashes []uintptr, values []uint32, seed uintptr) {
    40  	MultiHashUint32Array(hashes, sparse.MakeUint32Array(values), seed)
    41  }
    42  
    43  func MultiHash64(hashes []uintptr, values []uint64, seed uintptr) {
    44  	MultiHashUint64Array(hashes, sparse.MakeUint64Array(values), seed)
    45  }
    46  
    47  func MultiHash128(hashes []uintptr, values [][16]byte, seed uintptr) {
    48  	MultiHashUint128Array(hashes, sparse.MakeUint128Array(values), seed)
    49  }