feat: optimize index build
This commit is contained in:
75
pkg/generic/queue.go
Normal file
75
pkg/generic/queue.go
Normal file
@ -0,0 +1,75 @@
|
||||
package generic
|
||||
|
||||
type Queue[T any] struct {
|
||||
queue []T
|
||||
}
|
||||
|
||||
func NewQueue[T any]() *Queue[T] {
|
||||
return &Queue[T]{queue: make([]T, 0)}
|
||||
}
|
||||
|
||||
func (q *Queue[T]) Push(v T) {
|
||||
q.queue = append(q.queue, v)
|
||||
}
|
||||
|
||||
func (q *Queue[T]) Pop() T {
|
||||
v := q.queue[0]
|
||||
q.queue = q.queue[1:]
|
||||
return v
|
||||
}
|
||||
|
||||
func (q *Queue[T]) Len() int {
|
||||
return len(q.queue)
|
||||
}
|
||||
|
||||
func (q *Queue[T]) IsEmpty() bool {
|
||||
return len(q.queue) == 0
|
||||
}
|
||||
|
||||
func (q *Queue[T]) Clear() {
|
||||
q.queue = nil
|
||||
}
|
||||
|
||||
func (q *Queue[T]) Peek() T {
|
||||
return q.queue[0]
|
||||
}
|
||||
|
||||
func (q *Queue[T]) PeekN(n int) []T {
|
||||
return q.queue[:n]
|
||||
}
|
||||
|
||||
func (q *Queue[T]) PopN(n int) []T {
|
||||
v := q.queue[:n]
|
||||
q.queue = q.queue[n:]
|
||||
return v
|
||||
}
|
||||
|
||||
func (q *Queue[T]) PopAll() []T {
|
||||
v := q.queue
|
||||
q.queue = nil
|
||||
return v
|
||||
}
|
||||
|
||||
func (q *Queue[T]) PopWhile(f func(T) bool) []T {
|
||||
var i int
|
||||
for i = 0; i < len(q.queue); i++ {
|
||||
if !f(q.queue[i]) {
|
||||
break
|
||||
}
|
||||
}
|
||||
v := q.queue[:i]
|
||||
q.queue = q.queue[i:]
|
||||
return v
|
||||
}
|
||||
|
||||
func (q *Queue[T]) PopUntil(f func(T) bool) []T {
|
||||
var i int
|
||||
for i = 0; i < len(q.queue); i++ {
|
||||
if f(q.queue[i]) {
|
||||
break
|
||||
}
|
||||
}
|
||||
v := q.queue[:i]
|
||||
q.queue = q.queue[i:]
|
||||
return v
|
||||
}
|
56
pkg/mq/mq.go
Normal file
56
pkg/mq/mq.go
Normal file
@ -0,0 +1,56 @@
|
||||
package mq
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/alist-org/alist/v3/pkg/generic"
|
||||
)
|
||||
|
||||
type Message[T any] struct {
|
||||
Content T
|
||||
}
|
||||
|
||||
type BasicConsumer[T any] func(Message[T])
|
||||
type AllConsumer[T any] func([]Message[T])
|
||||
|
||||
type MQ[T any] interface {
|
||||
Publish(Message[T])
|
||||
Consume(BasicConsumer[T])
|
||||
ConsumeAll(AllConsumer[T])
|
||||
Clear()
|
||||
}
|
||||
|
||||
type inMemoryMQ[T any] struct {
|
||||
queue generic.Queue[Message[T]]
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
func NewInMemoryMQ[T any]() MQ[T] {
|
||||
return &inMemoryMQ[T]{queue: *generic.NewQueue[Message[T]]()}
|
||||
}
|
||||
|
||||
func (mq *inMemoryMQ[T]) Publish(msg Message[T]) {
|
||||
mq.Lock()
|
||||
defer mq.Unlock()
|
||||
mq.queue.Push(msg)
|
||||
}
|
||||
|
||||
func (mq *inMemoryMQ[T]) Consume(consumer BasicConsumer[T]) {
|
||||
mq.Lock()
|
||||
defer mq.Unlock()
|
||||
for !mq.queue.IsEmpty() {
|
||||
consumer(mq.queue.Pop())
|
||||
}
|
||||
}
|
||||
|
||||
func (mq *inMemoryMQ[T]) ConsumeAll(consumer AllConsumer[T]) {
|
||||
mq.Lock()
|
||||
defer mq.Unlock()
|
||||
consumer(mq.queue.PopAll())
|
||||
}
|
||||
|
||||
func (mq *inMemoryMQ[T]) Clear() {
|
||||
mq.Lock()
|
||||
defer mq.Unlock()
|
||||
mq.queue.Clear()
|
||||
}
|
Reference in New Issue
Block a user