This commit is contained in:
47
internal/queue/queue.go
Normal file
47
internal/queue/queue.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package queue
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Queue struct {
|
||||
ch chan int64
|
||||
mu sync.Mutex
|
||||
pending map[int64]struct{}
|
||||
}
|
||||
|
||||
func New(size int) *Queue {
|
||||
return &Queue{ch: make(chan int64, size), pending: make(map[int64]struct{})}
|
||||
}
|
||||
func (q *Queue) Enqueue(id int64) bool {
|
||||
if id <= 0 {
|
||||
return false
|
||||
}
|
||||
q.mu.Lock()
|
||||
if _, ok := q.pending[id]; ok {
|
||||
q.mu.Unlock()
|
||||
return false
|
||||
}
|
||||
q.pending[id] = struct{}{}
|
||||
q.mu.Unlock()
|
||||
select {
|
||||
case q.ch <- id:
|
||||
return true
|
||||
default:
|
||||
q.mu.Lock()
|
||||
delete(q.pending, id)
|
||||
q.mu.Unlock()
|
||||
return false
|
||||
}
|
||||
}
|
||||
func (q *Queue) Next(ctx context.Context) (int64, bool) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return 0, false
|
||||
case id := <-q.ch:
|
||||
return id, true
|
||||
}
|
||||
}
|
||||
func (q *Queue) Done(id int64) { q.mu.Lock(); delete(q.pending, id); q.mu.Unlock() }
|
||||
func (q *Queue) Len() int { return len(q.ch) }
|
||||
Reference in New Issue
Block a user