Clash.Meta/common/queue/queue.go

74 lines
1.2 KiB
Go
Raw Normal View History

package queue
import (
"sync"
2023-08-26 21:19:53 +08:00
"github.com/samber/lo"
)
// Queue is a simple concurrent safe queue
2022-04-06 01:07:08 +08:00
type Queue[T any] struct {
items []T
lock sync.RWMutex
}
// Put add the item to the queue.
2022-04-06 01:07:08 +08:00
func (q *Queue[T]) Put(items ...T) {
if len(items) == 0 {
return
}
q.lock.Lock()
q.items = append(q.items, items...)
q.lock.Unlock()
}
// Pop returns the head of items.
2022-04-06 01:07:08 +08:00
func (q *Queue[T]) Pop() T {
if len(q.items) == 0 {
2023-08-26 21:19:53 +08:00
return lo.Empty[T]()
}
q.lock.Lock()
head := q.items[0]
q.items = q.items[1:]
q.lock.Unlock()
return head
}
2019-09-26 10:08:50 +08:00
// Last returns the last of item.
2022-04-06 01:07:08 +08:00
func (q *Queue[T]) Last() T {
if len(q.items) == 0 {
2023-08-26 21:19:53 +08:00
return lo.Empty[T]()
}
q.lock.RLock()
2019-09-26 10:08:50 +08:00
last := q.items[len(q.items)-1]
q.lock.RUnlock()
2019-09-26 10:08:50 +08:00
return last
}
// Copy get the copy of queue.
2022-04-06 01:07:08 +08:00
func (q *Queue[T]) Copy() []T {
items := []T{}
q.lock.RLock()
items = append(items, q.items...)
q.lock.RUnlock()
return items
}
// Len returns the number of items in this queue.
2022-04-06 01:07:08 +08:00
func (q *Queue[T]) Len() int64 {
q.lock.Lock()
defer q.lock.Unlock()
return int64(len(q.items))
}
// New is a constructor for a new concurrent safe queue.
2022-04-06 01:07:08 +08:00
func New[T any](hint int64) *Queue[T] {
return &Queue[T]{
items: make([]T, 0, hint),
}
}