1// Copyright 2023 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build !purego
6
7package maphash
8
9import (
10	"unsafe"
11)
12
13//go:linkname runtime_rand runtime.rand
14func runtime_rand() uint64
15
16//go:linkname runtime_memhash runtime.memhash
17//go:noescape
18func runtime_memhash(p unsafe.Pointer, seed, s uintptr) uintptr
19
20func rthash(buf []byte, seed uint64) uint64 {
21	if len(buf) == 0 {
22		return seed
23	}
24	len := len(buf)
25	// The runtime hasher only works on uintptr. For 64-bit
26	// architectures, we use the hasher directly. Otherwise,
27	// we use two parallel hashers on the lower and upper 32 bits.
28	if unsafe.Sizeof(uintptr(0)) == 8 {
29		return uint64(runtime_memhash(unsafe.Pointer(&buf[0]), uintptr(seed), uintptr(len)))
30	}
31	lo := runtime_memhash(unsafe.Pointer(&buf[0]), uintptr(seed), uintptr(len))
32	hi := runtime_memhash(unsafe.Pointer(&buf[0]), uintptr(seed>>32), uintptr(len))
33	return uint64(hi)<<32 | uint64(lo)
34}
35
36func rthashString(s string, state uint64) uint64 {
37	buf := unsafe.Slice(unsafe.StringData(s), len(s))
38	return rthash(buf, state)
39}
40
41func randUint64() uint64 {
42	return runtime_rand()
43}
44