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