7 changed files with 276 additions and 20 deletions
@ -0,0 +1,59 @@
|
||||
package container |
||||
|
||||
import ( |
||||
"cmp" |
||||
"container/heap" |
||||
) |
||||
|
||||
// 堆封装
|
||||
type heapQueue[T any, C cmp.Ordered] struct { |
||||
queue []T |
||||
compare func(T) C |
||||
} |
||||
|
||||
func (h *heapQueue[T, C]) Less(i, j int) bool { |
||||
return h.compare(h.queue[i]) < h.compare(h.queue[j]) |
||||
} |
||||
|
||||
func (h *heapQueue[T, C]) Swap(i, j int) { |
||||
h.queue[i], h.queue[j] = h.queue[j], h.queue[i] |
||||
} |
||||
|
||||
func (h *heapQueue[T, C]) Len() int { |
||||
return len(h.queue) |
||||
} |
||||
|
||||
func (h *heapQueue[T, C]) Pop() (v any) { |
||||
h.queue, v = h.queue[:h.Len()-1], h.queue[h.Len()-1] |
||||
return |
||||
} |
||||
|
||||
func (h *heapQueue[T, C]) Push(v any) { |
||||
h.queue = append(h.queue, v.(T)) |
||||
} |
||||
|
||||
// Heap 封装堆操作
|
||||
type Heap[T any, C cmp.Ordered] struct { |
||||
queue *heapQueue[T, C] |
||||
} |
||||
|
||||
func NewHeap[T any, C cmp.Ordered](compare func(T) C) *Heap[T, C] { |
||||
return &Heap[T, C]{ |
||||
queue: &heapQueue[T, C]{compare: compare}, |
||||
} |
||||
} |
||||
|
||||
func (h *Heap[T, C]) Push(v T) { |
||||
heap.Push(h.queue, v) |
||||
} |
||||
|
||||
func (h *Heap[T, C]) Pop() T { |
||||
return heap.Pop(h.queue).(T) |
||||
} |
||||
|
||||
func (h *Heap[T, C]) Peek() (v T, ok bool) { |
||||
if h.queue.Len() == 0 { |
||||
return v, false |
||||
} |
||||
return h.queue.queue[0], true |
||||
} |
||||
@ -0,0 +1,56 @@
|
||||
package timer |
||||
|
||||
import ( |
||||
"cmp" |
||||
"sig-pub/pkg/utils/container" |
||||
"sync" |
||||
"sync/atomic" |
||||
"time" |
||||
) |
||||
|
||||
type timerTask struct { |
||||
ExecuteAt int64 |
||||
Canceled atomic.Bool |
||||
Handler func() |
||||
} |
||||
|
||||
// Timer todo 使用二叉树堆的定时任务执行器
|
||||
type Timer[T any] struct { |
||||
mu sync.RWMutex |
||||
heap *container.Heap[T, int64] |
||||
tick time.Duration |
||||
ticker *time.Ticker |
||||
} |
||||
|
||||
func NewTimer[T any, C cmp.Ordered](tick time.Duration, compare func(T) int64) *Timer[T] { |
||||
return &Timer[T]{ |
||||
heap: container.NewHeap(compare), |
||||
tick: tick, |
||||
} |
||||
} |
||||
|
||||
func (t *Timer[T]) Init() { |
||||
t.ticker = time.NewTicker(t.tick) |
||||
go func() { |
||||
for { |
||||
now, ok := <-t.ticker.C |
||||
if !ok { |
||||
return |
||||
} |
||||
t.mu.RLock() |
||||
v, ok := t.heap.Peek() |
||||
t.mu.RUnlock() |
||||
if !ok { |
||||
continue |
||||
} |
||||
_, _ = now, v |
||||
// todo handler
|
||||
} |
||||
}() |
||||
// time.Unix()
|
||||
// t.ticker.C
|
||||
} |
||||
|
||||
func (t *Timer[T]) Push(v T, duration time.Duration) { |
||||
t.heap.Push(v) |
||||
} |
||||
@ -0,0 +1,41 @@
|
||||
package timer |
||||
|
||||
import ( |
||||
"container/heap" |
||||
"fmt" |
||||
"testing" |
||||
) |
||||
|
||||
type myHeap []int |
||||
|
||||
func (h *myHeap) Less(i, j int) bool { |
||||
return (*h)[i] < (*h)[j] |
||||
} |
||||
|
||||
func (h *myHeap) Swap(i, j int) { |
||||
(*h)[i], (*h)[j] = (*h)[j], (*h)[i] |
||||
} |
||||
|
||||
func (h *myHeap) Len() int { |
||||
return len(*h) |
||||
} |
||||
|
||||
func (h *myHeap) Pop() (v any) { |
||||
*h, v = (*h)[:h.Len()-1], (*h)[h.Len()-1] |
||||
return |
||||
} |
||||
|
||||
func (h *myHeap) Push(v any) { |
||||
*h = append(*h, v.(int)) |
||||
} |
||||
|
||||
func TestMyHelp(t *testing.T) { |
||||
h := new(myHeap) |
||||
for _, v := range []int{5, 3, 8, 1, 2, 7} { |
||||
heap.Push(h, v) |
||||
} |
||||
fmt.Println(h) |
||||
for range len(*h) { |
||||
fmt.Println(heap.Pop(h), h) |
||||
} |
||||
} |
||||
Loading…
Reference in new issue