1
0
mirror of https://github.com/charlienet/go-mixed.git synced 2026-07-14 08:17:26 +08:00
Files
go-mixed/concurrent/delay_queue/mem_store.go
T
Charlie c44a325384 fix: 修复多处并发安全问题及锁实现重构
locker: 导出 RWLocker/EmptyLocker 接口, 新增 WithRWLocker, 重构
  SourceLocker 竞态、Synchronize 数据竞态

collections/linked_list: 补齐 ForEach/Size/GetAt/RemoveAt/ToList
  等方法的锁保护
collections/queue,stack: Peek/Size/IsEmpty 加锁
collections/list/linked_list: Front/Back/GetAt 加锁
maps: rwlock_map.Exist/Count, hash_map.Count 加锁
delay_queue/mem_store: Pop 原子化、Len/IsEmpty 加锁
cleanup_guard: Run() 检查 enable 标志
sets/ketama: 修复接口变更导致的 nil 空指针
2026-06-05 10:45:08 +08:00

98 lines
1.4 KiB
Go

package delayqueue
import (
"container/heap"
"context"
"sync"
"time"
)
type delayedQueue []Delayed
type memStore[T Delayed] struct {
mu sync.Mutex
h *delayedQueue
wakeup chan struct{}
}
func (q delayedQueue) Len() int {
return len(q)
}
func (q delayedQueue) Less(i, j int) bool {
return q[i].Delay().Before(q[j].Delay())
}
func (q delayedQueue) Swap(i, j int) {
q[i], q[j] = q[j], q[i]
}
func (q *delayedQueue) Push(x any) {
*q = append(*q, x.(Delayed))
}
func (h *delayedQueue) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}
func newMemStore[T Delayed]() *memStore[T] {
store := &memStore[T]{
h: new(delayedQueue),
wakeup: make(chan struct{}, 1),
}
heap.Init(store.h)
return store
}
func (s *memStore[T]) Push(ctx context.Context, v T) error {
s.mu.Lock()
defer s.mu.Unlock()
heap.Push(s.h, v)
return nil
}
func (s *memStore[T]) Pop() (T, error) {
for {
s.mu.Lock()
if s.h.Len() > 0 {
v := s.h.Pop().(T)
s.mu.Unlock()
return v, nil
}
s.mu.Unlock()
time.Sleep(time.Millisecond * 10)
}
}
func (s *memStore[T]) Peek() (T, bool) {
s.mu.Lock()
defer s.mu.Unlock()
if s.h.Len() > 0 {
return (*s.h)[0].(T), true
}
return *new(T), false
}
func (s *memStore[T]) Len() int {
s.mu.Lock()
defer s.mu.Unlock()
return s.h.Len()
}
func (s *memStore[T]) IsEmpty() bool {
s.mu.Lock()
defer s.mu.Unlock()
return s.h.Len() == 0
}