/
map.go
57 lines (49 loc) · 1.86 KB
/
map.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package unsafe
import (
"hash/maphash"
"unsafe"
)
func UnsafeHashOf[T comparable]() func(seed maphash.Seed, v T) uint64 {
h := getHashFunc[T](map[T]struct{}{})
return func(seed maphash.Seed, v T) uint64 {
return h.Sum64(seed, v)
}
}
// internal/abi/type.go -> Type
type abiType struct {
Size_ uintptr
PtrBytes uintptr // number of (prefix) bytes in the type that can contain pointers
Hash uint32 // hash of type; avoids computation in hash tables
TFlag uint8 // extra type information flags
Align_ uint8 // alignment of variable with this type
FieldAlign_ uint8 // alignment of struct field with this type
Kind_ uint8 // enumeration for C
// function for comparing objects of this type
// (ptr to object A, ptr to object B) -> ==?
Equal func(unsafe.Pointer, unsafe.Pointer) bool
// GCData stores the GC type data for the garbage collector.
// If the KindGCProg bit is set in kind, GCData is a GC program.
// Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
GCData *byte
Str int32 // string form
PtrToThis int32 // type for pointer to this type, may be zero
}
// internal/abi/type.go -> MapType
type abiMapType[T comparable] struct {
abiType
Key *abiType
Elem *abiType
Bucket *abiType // internal type representing a hash bucket
// function for hashing keys (ptr to key, seed) -> hash
Hasher hashFunc[T]
KeySize uint8 // size of key slot
ValueSize uint8 // size of elem slot
BucketSize uint16 // size of bucket
Flags uint32
}
type hashFunc[T comparable] func(value *T, seed maphash.Seed) uintptr
func (h hashFunc[T]) Sum64(seed maphash.Seed, v T) uint64 { return uint64(h(&v, seed)) }
type emptyInterface struct{ typ *abiType }
func getHashFunc[T comparable](v interface{}) hashFunc[T] {
return (*abiMapType[T])(unsafe.Pointer((*emptyInterface)(unsafe.Pointer(&v)).typ)).Hasher
}