github.com/primecitizens/pcz/std@v0.2.1/core/hash/hash32.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright 2023 The Prime Citizens
     3  //
     4  // Copyright 2014 The Go Authors. All rights reserved.
     5  // Use of this source code is governed by a BSD-style
     6  // license that can be found in the LICENSE file.
     7  
     8  // Hashing algorithm inspired by
     9  // wyhash: https://github.com/wangyi-fudan/wyhash/blob/ceb019b530e2c1c14d70b79bfa2bc49de7d95bc1/Modern%20Non-Cryptographic%20Hash%20Function%20and%20Pseudorandom%20Number%20Generator.pdf
    10  
    11  //go:build 386 || arm || mips || mipsle
    12  
    13  package hash
    14  
    15  import (
    16  	"unsafe"
    17  
    18  	"github.com/primecitizens/pcz/std/core/mem"
    19  )
    20  
    21  func MemHash(p unsafe.Pointer, seed, s uintptr) uintptr {
    22  	a, b := mix32(uint32(seed), uint32(s^hashkey[0]))
    23  	if s == 0 {
    24  		return uintptr(a ^ b)
    25  	}
    26  	for ; s > 8; s -= 8 {
    27  		a ^= mem.ReadUnaligned32(p)
    28  		b ^= mem.ReadUnaligned32(unsafe.Add(p, 4))
    29  		a, b = mix32(a, b)
    30  		p = unsafe.Add(p, 8)
    31  	}
    32  	if s >= 4 {
    33  		a ^= mem.ReadUnaligned32(p)
    34  		b ^= mem.ReadUnaligned32(unsafe.Add(p, s-4))
    35  	} else {
    36  		t := uint32(*(*byte)(p))
    37  		t |= uint32(*(*byte)(unsafe.Add(p, s>>1))) << 8
    38  		t |= uint32(*(*byte)(unsafe.Add(p, s-1))) << 16
    39  		b ^= t
    40  	}
    41  	a, b = mix32(a, b)
    42  	a, b = mix32(a, b)
    43  	return uintptr(a ^ b)
    44  }
    45  
    46  func MemHash32(p unsafe.Pointer, seed uintptr) uintptr {
    47  	a, b := mix32(uint32(seed), uint32(4^hashkey[0]))
    48  	t := mem.ReadUnaligned32(p)
    49  	a ^= t
    50  	b ^= t
    51  	a, b = mix32(a, b)
    52  	a, b = mix32(a, b)
    53  	return uintptr(a ^ b)
    54  }
    55  
    56  func MemHash64(p unsafe.Pointer, seed uintptr) uintptr {
    57  	a, b := mix32(uint32(seed), uint32(8^hashkey[0]))
    58  	a ^= mem.ReadUnaligned32(p)
    59  	b ^= mem.ReadUnaligned32(unsafe.Add(p, 4))
    60  	a, b = mix32(a, b)
    61  	a, b = mix32(a, b)
    62  	return uintptr(a ^ b)
    63  }
    64  
    65  func mix32(a, b uint32) (uint32, uint32) {
    66  	c := uint64(a^uint32(hashkey[1])) * uint64(b^uint32(hashkey[2]))
    67  	return uint32(c), uint32(c >> 32)
    68  }