-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdelay_map.go
99 lines (87 loc) · 1.8 KB
/
delay_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
package utp_go
import (
"sync"
"time"
"github.com/ethereum/go-ethereum/log"
)
type delayMap[P any] struct {
lock sync.Mutex
innerMap map[any]*delayItem[P]
itemTimeoutCh chan *delayItem[P]
shouldLock bool
}
type delayItem[P any] struct {
Item P
Key any
timer *time.Timer
}
func newDelayMap[P any]() *delayMap[P] {
return &delayMap[P]{
innerMap: make(map[any]*delayItem[P]),
itemTimeoutCh: make(chan *delayItem[P], 100),
shouldLock: false,
}
}
func (m *delayMap[P]) timeoutCh() chan *delayItem[P] {
return m.itemTimeoutCh
}
func (m *delayMap[P]) put(key any, value P, timeout time.Duration) {
if m.shouldLock {
m.lock.Lock()
defer m.lock.Unlock()
}
item := &delayItem[P]{
Key: key,
Item: value,
}
timer := time.AfterFunc(timeout, func() {
m.itemTimeoutCh <- item
})
item.timer = timer
m.innerMap[key] = item
}
func (m *delayMap[P]) get(key any) P {
if m.shouldLock {
m.lock.Lock()
defer m.lock.Unlock()
}
return m.innerMap[key].Item
}
func (m *delayMap[P]) retain(shouldRemove func(key any) bool) {
if m.shouldLock {
m.lock.Lock()
defer m.lock.Unlock()
}
for k := range m.innerMap {
if shouldRemove(k) {
m.remove(k)
}
}
}
func (m *delayMap[P]) remove(key any) {
if m.shouldLock {
m.lock.Lock()
defer m.lock.Unlock()
}
if log.Root().Enabled(BASE_CONTEXT, log.LevelDebug) {
log.Debug("delay map key count before", "count", len(m.innerMap))
}
if item, ok := m.innerMap[key]; ok {
item.timer.Stop()
}
delete(m.innerMap, key)
if log.Root().Enabled(BASE_CONTEXT, log.LevelDebug) {
log.Debug("delay map key count after", "count", len(m.innerMap))
}
}
func (m *delayMap[P]) keys() []any {
if m.shouldLock {
m.lock.Lock()
defer m.lock.Unlock()
}
var keys []any
for k := range m.innerMap {
keys = append(keys, k)
}
return keys
}