-
Notifications
You must be signed in to change notification settings - Fork 1
/
timer_queue.go
122 lines (105 loc) · 2.14 KB
/
timer_queue.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 utils
import (
"container/heap"
)
type TimeOuter interface {
TimeOut(int64)
}
type Timer struct {
TimeOuter
id uint32
end int64 //结束时间
interval int64 //迭代周期
index int
}
type TimerQueue []*Timer
func (this TimerQueue) Len() int {
return len(this)
}
func (this TimerQueue) Less(i, j int) bool {
return this[i].end < this[j].end
}
func (this TimerQueue) Swap(i, j int) {
this[i], this[j] = this[j], this[i]
this[i].index = i
this[j].index = j
}
func (this *TimerQueue) Push(x interface{}) {
tmp := *this
n := len(tmp)
tmp = tmp[0 : n+1]
timer := x.(*Timer)
timer.index = n
tmp[n] = timer
*this = tmp
}
func (this *TimerQueue) Pop() interface{} {
tmp := *this
n := len(tmp)
timer := tmp[n-1]
tmp[n-1] = nil
timer.index = -1
*this = tmp[0 : n-1]
return timer
}
type TimerManager struct {
id uint32
tq TimerQueue
}
func NewTimerManager(size int) *TimerManager {
if size == 0 {
size = 1024
}
return &TimerManager{tq: make([]*Timer, 0, size)}
}
func (this *TimerManager) AddTimer(i TimeOuter, e int64, iv int64) uint32 {
if cap(this.tq) <= len(this.tq) {
return 0
}
timer := &Timer{TimeOuter: i, interval: iv, end: e}
this.id++
timer.id = this.id
heap.Push(&this.tq, timer)
return timer.id
}
func (this *TimerManager) RemoveTimer(id uint32) {
for _, timer := range this.tq {
if timer.id == id {
heap.Remove(&this.tq, timer.index)
return
}
}
}
var queue *Queue = &Queue{}
func (this *TimerManager) Run(now int64, limit int) {
for len(this.tq) > 0 {
tmp := this.tq[0]
if tmp.end <= now {
timer := heap.Pop(&this.tq).(*Timer)
queue.Push(timer.TimeOuter)
if timer.interval > 0 {
timer.end += timer.interval
heap.Push(&this.tq, timer)
}
} else {
break
}
if limit > 0 && queue.Len() >= limit {
break
}
}
for queue.Len() > 0 {
queue.Pop().(TimeOuter).TimeOut(now)
}
}
func (this *TimerManager) dump() {
queue := &Queue{}
for len(this.tq) > 0 {
timer := heap.Pop(&this.tq).(*Timer)
queue.Push(timer)
println("Timer:", timer.id, timer.index, timer.end, timer.interval)
}
for queue.Len() > 0 {
heap.Push(&this.tq, queue.Pop().(*Timer))
}
}