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
|
package container
import (
"slices"
"sync"
)
// M is ordered and concurent safe map implementation.
type M[K comparable, V any] struct {
m map[K]V
k []K
mu sync.RWMutex
}
// Make returns new instance with `capacity` initial capacity.
func Make[K comparable, V any](capacity int) M[K, V] {
return M[K, V]{
m: make(map[K]V, capacity),
k: make([]K, 0, capacity),
}
}
// Get value `V` by key `k K`. Returns zero value if the key is absent.
func (m *M[K, V]) Get(k K) V {
m.mu.RLock()
defer m.mu.RUnlock()
return m.m[k]
}
// Get2 value `v V` by key `k K` and a presence flag `ok bool`. Returns
// `(value, true)` if the key exists, and `(zero value, false)` if the key is
// absent.
func (m *M[K, V]) Get2(k K) (v V, ok bool) {
m.mu.RLock()
defer m.mu.RUnlock()
v, ok = m.m[k]
return v, ok
}
// Has returns true if key `k K` exists in map.
func (m *M[K, V]) Has(k K) bool {
m.mu.RLock()
defer m.mu.RUnlock()
_, ok := m.m[k]
return ok
}
// Set value `v V` to key `k K`.
func (m *M[K, V]) Set(k K, v V) {
m.mu.Lock()
defer m.mu.Unlock()
if _, exists := m.m[k]; !exists {
m.k = append(m.k, k)
}
m.m[k] = v
}
// Delete key `k K` from map.
func (m *M[K, V]) Delete(k K) {
m.mu.Lock()
defer m.mu.Unlock()
if _, ok := m.m[k]; !ok {
return
}
idx := slices.Index(m.k, k)
m.k = slices.Delete(m.k, idx, idx+1)
delete(m.m, k)
}
// Keys is iterator over keys.
func (m *M[K, V]) Keys(yield func(K) bool) {
for _, k := range m.k {
if !yield(k) {
break
}
}
}
// Values is iterator over values.
func (m *M[K, V]) Values(yield func(V) bool) {
for _, k := range m.k {
if !yield(m.m[k]) {
break
}
}
}
// Entries is iterator over key:value pairs.
func (m *M[K, V]) Entries(yield func(K, V) bool) {
for _, k := range m.k {
if !yield(k, m.m[k]) {
break
}
}
}
|