...

Source file src/github.com/zeebo/xxh3/utils.go

Documentation: github.com/zeebo/xxh3

     1  package xxh3
     2  
     3  import (
     4  	"math/bits"
     5  	"unsafe"
     6  )
     7  
     8  // Uint128 is a 128 bit value.
     9  // The actual value can be thought of as u.Hi<<64 | u.Lo.
    10  type Uint128 struct {
    11  	Hi, Lo uint64
    12  }
    13  
    14  // Bytes returns the uint128 as an array of bytes in canonical form (big-endian encoded).
    15  func (u Uint128) Bytes() [16]byte {
    16  	return [16]byte{
    17  		byte(u.Hi >> 0x38), byte(u.Hi >> 0x30), byte(u.Hi >> 0x28), byte(u.Hi >> 0x20),
    18  		byte(u.Hi >> 0x18), byte(u.Hi >> 0x10), byte(u.Hi >> 0x08), byte(u.Hi),
    19  		byte(u.Lo >> 0x38), byte(u.Lo >> 0x30), byte(u.Lo >> 0x28), byte(u.Lo >> 0x20),
    20  		byte(u.Lo >> 0x18), byte(u.Lo >> 0x10), byte(u.Lo >> 0x08), byte(u.Lo),
    21  	}
    22  }
    23  
    24  type (
    25  	ptr = unsafe.Pointer
    26  	ui  = uintptr
    27  
    28  	u8   = uint8
    29  	u32  = uint32
    30  	u64  = uint64
    31  	u128 = Uint128
    32  )
    33  
    34  type str struct {
    35  	p ptr
    36  	l uint
    37  }
    38  
    39  func readU8(p ptr, o ui) uint8 {
    40  	return *(*uint8)(ptr(ui(p) + o))
    41  }
    42  
    43  func readU16(p ptr, o ui) uint16 {
    44  	b := (*[2]byte)(ptr(ui(p) + o))
    45  	return uint16(b[0]) | uint16(b[1])<<8
    46  }
    47  
    48  func readU32(p ptr, o ui) uint32 {
    49  	b := (*[4]byte)(ptr(ui(p) + o))
    50  	return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
    51  }
    52  
    53  func readU64(p ptr, o ui) uint64 {
    54  	b := (*[8]byte)(ptr(ui(p) + o))
    55  	return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
    56  		uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
    57  }
    58  
    59  func writeU64(p ptr, o ui, v u64) {
    60  	b := (*[8]byte)(ptr(ui(p) + o))
    61  	b[0] = byte(v)
    62  	b[1] = byte(v >> 8)
    63  	b[2] = byte(v >> 16)
    64  	b[3] = byte(v >> 24)
    65  	b[4] = byte(v >> 32)
    66  	b[5] = byte(v >> 40)
    67  	b[6] = byte(v >> 48)
    68  	b[7] = byte(v >> 56)
    69  }
    70  
    71  const secretSize = 192
    72  
    73  func initSecret(secret ptr, seed u64) {
    74  	for i := ui(0); i < secretSize/16; i++ {
    75  		lo := readU64(key, 16*i) + seed
    76  		hi := readU64(key, 16*i+8) - seed
    77  		writeU64(secret, 16*i, lo)
    78  		writeU64(secret, 16*i+8, hi)
    79  	}
    80  }
    81  
    82  func xxh64AvalancheSmall(x u64) u64 {
    83  	// x ^= x >> 33                    // x must be < 32 bits
    84  	// x ^= u64(key32_000 ^ key32_004) // caller must do this
    85  	x *= prime64_2
    86  	x ^= x >> 29
    87  	x *= prime64_3
    88  	x ^= x >> 32
    89  	return x
    90  }
    91  
    92  func xxhAvalancheSmall(x u64) u64 {
    93  	x ^= x >> 33
    94  	x *= prime64_2
    95  	x ^= x >> 29
    96  	x *= prime64_3
    97  	x ^= x >> 32
    98  	return x
    99  }
   100  
   101  func xxh64AvalancheFull(x u64) u64 {
   102  	x ^= x >> 33
   103  	x *= prime64_2
   104  	x ^= x >> 29
   105  	x *= prime64_3
   106  	x ^= x >> 32
   107  	return x
   108  }
   109  
   110  func xxh3Avalanche(x u64) u64 {
   111  	x ^= x >> 37
   112  	x *= 0x165667919e3779f9
   113  	x ^= x >> 32
   114  	return x
   115  }
   116  
   117  func rrmxmx(h64 u64, len u64) u64 {
   118  	h64 ^= bits.RotateLeft64(h64, 49) ^ bits.RotateLeft64(h64, 24)
   119  	h64 *= 0x9fb21c651e98df25
   120  	h64 ^= (h64 >> 35) + len
   121  	h64 *= 0x9fb21c651e98df25
   122  	h64 ^= (h64 >> 28)
   123  	return h64
   124  }
   125  
   126  func mulFold64(x, y u64) u64 {
   127  	hi, lo := bits.Mul64(x, y)
   128  	return hi ^ lo
   129  }
   130  

View as plain text