-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmap.go
164 lines (142 loc) · 4.42 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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// Package gsync Description: A generic wrapper around sync.Map.
package gsync
import (
"fmt"
"strings"
"sync"
)
// Map is a generic wrapper around sync.Map.
type Map[K comparable, V any] struct {
// data is the underlying sync.Map.
data sync.Map
}
// Range calls f sequentially for each key and value present in the map.
// If f returns false, range stops the iteration.
func (m *Map[K, V]) Range(f func(key K, value V) bool) {
m.data.Range(func(key, value any) bool {
return f(key.(K), value.(V))
})
}
// Load returns the value stored in the map for a key, or nil if no
// value is present.
// The ok result indicates whether value was found in the map.
func (m *Map[K, V]) Load(key K) (value V, ok bool) {
v, ok := m.data.Load(key)
if !ok {
return value, ok
}
return v.(V), ok
}
// Get returns Load result ignoring ok value.
func (m *Map[K, V]) Get(key K) (value V) {
value, _ = m.Load(key)
return
}
// Has returns true if key exists in the map.
func (m *Map[K, V]) Has(key K) bool {
_, ok := m.data.Load(key)
return ok
}
// LoadAndDelete deletes the value for a key, returning the previous value if any.
// The loaded result reports whether the key was present.
func (m *Map[K, V]) LoadAndDelete(key K) (value V, loaded bool) {
v, loaded := m.data.LoadAndDelete(key)
if !loaded {
return value, loaded
}
return v.(V), loaded
}
// Store sets the value for a key.
func (m *Map[K, V]) Store(key K, value V) {
m.data.Store(key, value)
}
// LoadOrStore returns the existing value for the key if present.
// Otherwise, it stores and returns the given value.
// The loaded result is true if the value was loaded, false if stored.
func (m *Map[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool) {
a, loaded := m.data.LoadOrStore(key, value)
return a.(V), loaded
}
// GetOrStore returns the existing value for the key if present.
// Otherwise, it stores and returns the given value.
// The loaded result is true if the value was loaded, false if stored.
func (m *Map[K, V]) GetOrStore(key K, value V) (actual V) {
a, _ := m.data.LoadOrStore(key, value)
return a.(V)
}
// Delete deletes the value for a key.
func (m *Map[K, V]) Delete(key K) {
m.data.Delete(key)
}
// Swap swaps the value for a key and returns the previous value if any.
// The loaded result reports whether the key was present.
func (m *Map[K, V]) Swap(key K, new V) (old V, loaded bool) {
a, loaded := m.data.Swap(key, new)
return a.(V), loaded
}
// CompareAndSwap swaps the old and new values for key
// if the value stored in the map is equal to old.
// The old value must be of a comparable type.
func (m *Map[K, V]) CompareAndSwap(key K, old, new V) bool {
return m.data.CompareAndSwap(key, old, new)
}
// CompareAndDelete deletes the entry for key if its value is equal to old.
// The old value must be of a comparable type.
func (m *Map[K, V]) CompareAndDelete(key K, value V) bool {
return m.data.CompareAndDelete(key, value)
}
// Compute LoadOrCompute returns the existing value for the key if present.
func (m *Map[K, V]) Compute(key K, f func(old V) V) {
m.Store(key, f(m.Get(key)))
}
// ComputeAndGet LoadOrCompute returns the existing value for the key if present.
func (m *Map[K, V]) ComputeAndGet(key K, f func(old V) V) V {
return m.GetOrStore(key, f(m.Get(key)))
}
// ComputeAndLoad LoadOrCompute returns the existing value for the key if present.
func (m *Map[K, V]) ComputeAndLoad(key K, f func(old V) V) (V, bool) {
return m.LoadOrStore(key, f(m.Get(key)))
}
// Len returns the number of items in the map.
func (m *Map[K, V]) Len() int {
l := 0
m.data.Range(func(key, value any) bool {
l++
return true
})
return l
}
// Keys returns all keys in the map.
func (m *Map[K, V]) Keys() []K {
keys := make([]K, 0)
m.data.Range(func(key, value any) bool {
keys = append(keys, key.(K))
return true
})
return keys
}
// Values returns all values in the map.
func (m *Map[K, V]) Values() []V {
values := make([]V, 0)
m.data.Range(func(key, value any) bool {
values = append(values, value.(V))
return true
})
return values
}
// Clear removes all items from the map.
func (m *Map[K, V]) Clear() {
m.data.Range(func(key, value any) bool {
m.data.Delete(key)
return true
})
}
// String returns a string representation of the map.
func (m *Map[K, V]) String() string {
var toPrint []string
m.Range(func(key K, value V) bool {
toPrint = append(toPrint, fmt.Sprintf("%v: %v", key, value))
return true
})
return fmt.Sprintf("{%v}", strings.Join(toPrint, ", "))
}