-
Notifications
You must be signed in to change notification settings - Fork 0
/
bigint_map.go
69 lines (60 loc) · 1.47 KB
/
bigint_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
58
59
60
61
62
63
64
65
66
67
68
69
package kademlia
import (
"math/big"
"runtime"
)
type bigIntMapEntry[T any] struct {
key *big.Int
value T
}
// bigIntMap is a map with big.Int keys. It offers a convenient and optimized way
// to relate some arbitrary types with a big.Int.
type bigIntMap[T any] struct {
m map[string]bigIntMapEntry[T]
}
// set sets the value for a key.
func (m *bigIntMap[T]) set(key *big.Int, value T) {
if m.m == nil {
m.m = make(map[string]bigIntMapEntry[T])
}
m.m[unsafeBigIntToString(key)] = bigIntMapEntry[T]{
key: key,
value: value,
}
runtime.KeepAlive(key)
}
// get returns the value stored in the map for a key, or zero value if no value
// is present. The ok result indicates whether value was found in the map.
func (m *bigIntMap[T]) get(key *big.Int) (value T, ok bool) {
if m.m != nil {
e, ok := m.m[unsafeBigIntToString(key)]
runtime.KeepAlive(key)
return e.value, ok
}
return
}
// contains returns true if the map contains some value associated with
// a given key.
func (m *bigIntMap[T]) contains(key *big.Int) bool {
_, ok := m.get(key)
return ok
}
func (m *bigIntMap[T]) first() (ret T) {
for _, v := range m.m {
ret = v.value
return
}
return
}
// forEach calls f sequentially for each key and value present in the map.
// If f returns false, it stops the iteration.
func (m *bigIntMap[T]) forEach(f func(key *big.Int, value T) bool) {
for _, v := range m.m {
if !f(v.key, v.value) {
return
}
}
}
func (m *bigIntMap[T]) len() int {
return len(m.m)
}