-
Notifications
You must be signed in to change notification settings - Fork 2
/
seqmap.go
122 lines (103 loc) · 2 KB
/
seqmap.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
package wpk
import (
"sync"
)
type kvpair[K comparable, T any] struct {
key K
val T
}
// SeqMap is thread-safe map with key-value pairs sequence
// in which they were placed into map.
type SeqMap[K comparable, T any] struct {
seq []kvpair[K, T]
idx map[K]int
mux sync.RWMutex
}
func (m *SeqMap[K, T]) Init(c int) {
m.mux.Lock()
defer m.mux.Unlock()
m.idx = make(map[K]int, c)
m.seq = make([]kvpair[K, T], 0, c)
}
func (m *SeqMap[K, T]) Len() int {
m.mux.RLock()
defer m.mux.RUnlock()
return len(m.seq)
}
func (m *SeqMap[K, T]) Has(key K) (ok bool) {
m.mux.RLock()
defer m.mux.RUnlock()
_, ok = m.idx[key]
return
}
func (m *SeqMap[K, T]) Peek(key K) (ret T, ok bool) {
m.mux.RLock()
defer m.mux.RUnlock()
var n int
if n, ok = m.idx[key]; ok {
ret = m.seq[n].val
}
return
}
func (m *SeqMap[K, T]) Poke(key K, val T) {
m.mux.Lock()
defer m.mux.Unlock()
var n, ok = m.idx[key]
if ok {
m.seq[n].val = val
} else {
m.idx[key] = len(m.seq)
m.seq = append(m.seq, kvpair[K, T]{
key: key,
val: val,
})
}
}
func (m *SeqMap[K, T]) Pop() (key K, val T, ok bool) {
m.mux.RLock()
defer m.mux.RUnlock()
if n := len(m.seq) - 1; n >= 0 {
key, val, ok = m.seq[n].key, m.seq[n].val, true
delete(m.idx, key)
m.seq = m.seq[:n]
}
return
}
func (m *SeqMap[K, T]) Push(key K, val T) (ok bool) {
m.mux.Lock()
defer m.mux.Unlock()
if _, ok = m.idx[key]; !ok {
m.idx[key] = len(m.seq)
m.seq = append(m.seq, kvpair[K, T]{
key: key,
val: val,
})
}
return
}
func (m *SeqMap[K, T]) Delete(key K) (ret T, ok bool) {
var n int
m.mux.Lock()
defer m.mux.Unlock()
if n, ok = m.idx[key]; ok {
ret = m.seq[n].val
delete(m.idx, key)
copy(m.seq[n:], m.seq[n+1:])
m.seq = m.seq[:len(m.seq)-1]
for i := n; i < len(m.seq); i++ {
m.idx[m.seq[i].key] = i
}
}
return
}
func (m *SeqMap[K, T]) Range(f func(K, T) bool) {
m.mux.Lock()
var s = make([]kvpair[K, T], len(m.seq))
copy(s, m.seq)
m.mux.Unlock()
for _, pair := range s {
if !f(pair.key, pair.val) {
return
}
}
}