2019-10-09 19:59:19 +03:00
|
|
|
package ants
|
|
|
|
|
|
|
|
import "time"
|
|
|
|
|
|
|
|
type loopQueue struct {
|
2019-10-20 13:22:13 +03:00
|
|
|
items []*goWorker
|
|
|
|
expiry []*goWorker
|
|
|
|
head int
|
|
|
|
tail int
|
|
|
|
size int
|
|
|
|
isFull bool
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
|
|
|
|
2019-10-09 22:02:04 +03:00
|
|
|
func newWorkerLoopQueue(size int) *loopQueue {
|
2019-10-20 13:22:13 +03:00
|
|
|
return &loopQueue{
|
|
|
|
items: make([]*goWorker, size),
|
|
|
|
size: size,
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (wq *loopQueue) len() int {
|
2019-10-20 13:22:13 +03:00
|
|
|
if wq.size == 0 {
|
2019-10-09 19:59:19 +03:00
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2019-10-20 13:22:13 +03:00
|
|
|
if wq.head == wq.tail {
|
|
|
|
if wq.isFull {
|
|
|
|
return wq.size
|
|
|
|
}
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
if wq.tail > wq.head {
|
|
|
|
return wq.tail - wq.head
|
|
|
|
}
|
|
|
|
|
|
|
|
return wq.size - wq.head + wq.tail
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func (wq *loopQueue) isEmpty() bool {
|
2019-10-20 13:22:13 +03:00
|
|
|
return wq.head == wq.tail && !wq.isFull
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
|
|
|
|
2019-10-09 22:02:04 +03:00
|
|
|
func (wq *loopQueue) insert(worker *goWorker) error {
|
2019-10-20 13:22:13 +03:00
|
|
|
if wq.size == 0 {
|
|
|
|
return errQueueIsReleased
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
|
|
|
|
2019-10-20 13:22:13 +03:00
|
|
|
if wq.isFull {
|
|
|
|
return errQueueIsFull
|
|
|
|
}
|
2019-10-09 19:59:19 +03:00
|
|
|
wq.items[wq.tail] = worker
|
2019-10-20 13:22:13 +03:00
|
|
|
wq.tail++
|
|
|
|
|
|
|
|
if wq.tail == wq.size {
|
|
|
|
wq.tail = 0
|
|
|
|
}
|
|
|
|
if wq.tail == wq.head {
|
|
|
|
wq.isFull = true
|
|
|
|
}
|
2019-10-09 19:59:19 +03:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-10-09 22:02:04 +03:00
|
|
|
func (wq *loopQueue) detach() *goWorker {
|
2019-10-20 13:22:13 +03:00
|
|
|
if wq.isEmpty() {
|
2019-10-09 19:59:19 +03:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
w := wq.items[wq.head]
|
2019-10-20 13:22:13 +03:00
|
|
|
wq.head++
|
|
|
|
if wq.head == wq.size {
|
|
|
|
wq.head = 0
|
|
|
|
}
|
|
|
|
wq.isFull = false
|
2019-10-09 19:59:19 +03:00
|
|
|
|
|
|
|
return w
|
|
|
|
}
|
|
|
|
|
2019-10-20 13:22:13 +03:00
|
|
|
func (wq *loopQueue) retrieveExpiry(duration time.Duration) []*goWorker {
|
|
|
|
if wq.isEmpty() {
|
2019-10-09 22:02:04 +03:00
|
|
|
return nil
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
wq.expiry = wq.expiry[:0]
|
|
|
|
expiryTime := time.Now().Add(-duration)
|
|
|
|
|
2019-10-20 13:22:13 +03:00
|
|
|
for !wq.isEmpty() {
|
2019-10-09 22:02:04 +03:00
|
|
|
if expiryTime.Before(wq.items[wq.head].recycleTime) {
|
|
|
|
break
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
2019-10-09 22:02:04 +03:00
|
|
|
wq.expiry = append(wq.expiry, wq.items[wq.head])
|
2019-10-20 13:22:13 +03:00
|
|
|
wq.head++
|
|
|
|
if wq.head == wq.size {
|
|
|
|
wq.head = 0
|
|
|
|
}
|
|
|
|
wq.isFull = false
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
2019-10-20 13:22:13 +03:00
|
|
|
|
2019-10-09 22:02:04 +03:00
|
|
|
return wq.expiry
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
|
|
|
|
2019-10-20 13:22:13 +03:00
|
|
|
func (wq *loopQueue) reset() {
|
|
|
|
if wq.isEmpty() {
|
2019-10-09 19:59:19 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-10-20 13:22:13 +03:00
|
|
|
Releasing:
|
|
|
|
if w := wq.detach(); w != nil {
|
|
|
|
w.task <- nil
|
|
|
|
goto Releasing
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
|
|
|
wq.items = wq.items[:0]
|
2019-10-20 13:22:13 +03:00
|
|
|
wq.size = 0
|
2019-10-09 19:59:19 +03:00
|
|
|
wq.head = 0
|
|
|
|
wq.tail = 0
|
|
|
|
}
|