Source file
src/runtime/hash64.go
1
2
3
4
5
6
7
8
9
10 package runtime
11
12 import (
13 "runtime/internal/math"
14 "unsafe"
15 )
16
17 const (
18 m5 = 0x1d8e4e27c47d124f
19 )
20
21 func memhashFallback(p unsafe.Pointer, seed, s uintptr) uintptr {
22 var a, b uintptr
23 seed ^= hashkey[0]
24 switch {
25 case s == 0:
26 return seed
27 case s < 4:
28 a = uintptr(*(*byte)(p))
29 a |= uintptr(*(*byte)(add(p, s>>1))) << 8
30 a |= uintptr(*(*byte)(add(p, s-1))) << 16
31 case s == 4:
32 a = r4(p)
33 b = a
34 case s < 8:
35 a = r4(p)
36 b = r4(add(p, s-4))
37 case s == 8:
38 a = r8(p)
39 b = a
40 case s <= 16:
41 a = r8(p)
42 b = r8(add(p, s-8))
43 default:
44 l := s
45 if l > 48 {
46 seed1 := seed
47 seed2 := seed
48 for ; l > 48; l -= 48 {
49 seed = mix(r8(p)^hashkey[1], r8(add(p, 8))^seed)
50 seed1 = mix(r8(add(p, 16))^hashkey[2], r8(add(p, 24))^seed1)
51 seed2 = mix(r8(add(p, 32))^hashkey[3], r8(add(p, 40))^seed2)
52 p = add(p, 48)
53 }
54 seed ^= seed1 ^ seed2
55 }
56 for ; l > 16; l -= 16 {
57 seed = mix(r8(p)^hashkey[1], r8(add(p, 8))^seed)
58 p = add(p, 16)
59 }
60 a = r8(add(p, l-16))
61 b = r8(add(p, l-8))
62 }
63
64 return mix(m5^s, mix(a^hashkey[1], b^seed))
65 }
66
67 func memhash32Fallback(p unsafe.Pointer, seed uintptr) uintptr {
68 a := r4(p)
69 return mix(m5^4, mix(a^hashkey[1], a^seed^hashkey[0]))
70 }
71
72 func memhash64Fallback(p unsafe.Pointer, seed uintptr) uintptr {
73 a := r8(p)
74 return mix(m5^8, mix(a^hashkey[1], a^seed^hashkey[0]))
75 }
76
77 func mix(a, b uintptr) uintptr {
78 hi, lo := math.Mul64(uint64(a), uint64(b))
79 return uintptr(hi ^ lo)
80 }
81
82 func r4(p unsafe.Pointer) uintptr {
83 return uintptr(readUnaligned32(p))
84 }
85
86 func r8(p unsafe.Pointer) uintptr {
87 return uintptr(readUnaligned64(p))
88 }
89
View as plain text