Source file
src/hash/maphash/maphash_runtime.go
1
2
3
4
5
6
7 package maphash
8
9 import (
10 "internal/abi"
11 "internal/goarch"
12 "unsafe"
13 )
14
15 const purego = false
16
17
18 func runtime_rand() uint64
19
20
21
22 func runtime_memhash(p unsafe.Pointer, seed, s uintptr) uintptr
23
24 func rthash(buf []byte, seed uint64) uint64 {
25 if len(buf) == 0 {
26 return seed
27 }
28 len := len(buf)
29
30
31
32 if goarch.PtrSize == 8 {
33 return uint64(runtime_memhash(unsafe.Pointer(&buf[0]), uintptr(seed), uintptr(len)))
34 }
35 lo := runtime_memhash(unsafe.Pointer(&buf[0]), uintptr(seed), uintptr(len))
36 hi := runtime_memhash(unsafe.Pointer(&buf[0]), uintptr(seed>>32), uintptr(len))
37 return uint64(hi)<<32 | uint64(lo)
38 }
39
40 func rthashString(s string, state uint64) uint64 {
41 buf := unsafe.Slice(unsafe.StringData(s), len(s))
42 return rthash(buf, state)
43 }
44
45 func randUint64() uint64 {
46 return runtime_rand()
47 }
48
49 func comparableHash[T comparable](v T, seed Seed) uint64 {
50 s := seed.s
51 var m map[T]struct{}
52 mTyp := abi.TypeOf(m)
53 hasher := (*abi.MapType)(unsafe.Pointer(mTyp)).Hasher
54 if goarch.PtrSize == 8 {
55 return uint64(hasher(abi.NoEscape(unsafe.Pointer(&v)), uintptr(s)))
56 }
57 lo := hasher(abi.NoEscape(unsafe.Pointer(&v)), uintptr(s))
58 hi := hasher(abi.NoEscape(unsafe.Pointer(&v)), uintptr(s>>32))
59 return uint64(hi)<<32 | uint64(lo)
60 }
61
62 func writeComparable[T comparable](h *Hash, v T) {
63 h.state.s = comparableHash(v, h.state)
64 }
65
View as plain text