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 }