mirror of https://github.com/jackc/pgx.git
76 lines
1.1 KiB
Plaintext
76 lines
1.1 KiB
Plaintext
package nbbconn
|
|
|
|
import (
|
|
"sync"
|
|
)
|
|
|
|
const minQueueLen = 8
|
|
|
|
type queue[T any] struct {
|
|
lock sync.Mutex
|
|
queue []T
|
|
r, w int
|
|
}
|
|
|
|
func (q *queue[T]) pushBack(item T) {
|
|
q.lock.Lock()
|
|
defer q.lock.Unlock()
|
|
|
|
if q.w >= len(q.queue) {
|
|
q.growQueue()
|
|
}
|
|
q.queue[q.w] = item
|
|
q.w++
|
|
}
|
|
|
|
func (q *queue[T]) pushFront(item T) {
|
|
q.lock.Lock()
|
|
defer q.lock.Unlock()
|
|
|
|
if q.w >= len(q.queue) {
|
|
q.growQueue()
|
|
}
|
|
copy(q.queue[q.r+1:q.w+1], q.queue[q.r:q.w])
|
|
q.queue[q.r] = item
|
|
q.w++
|
|
}
|
|
|
|
func (q *queue[T]) popFront() (T, bool) {
|
|
q.lock.Lock()
|
|
defer q.lock.Unlock()
|
|
|
|
if q.r == q.w {
|
|
var zero T
|
|
return zero, false
|
|
}
|
|
|
|
item := q.queue[q.r]
|
|
|
|
// Clear reference so it can be garbage collected.
|
|
var zero T
|
|
q.queue[q.r] = zero
|
|
|
|
q.r++
|
|
|
|
if q.r == q.w {
|
|
q.r = 0
|
|
q.w = 0
|
|
if len(q.queue) > minQueueLen {
|
|
q.queue = make([]T, minQueueLen)
|
|
}
|
|
}
|
|
|
|
return item, true
|
|
}
|
|
|
|
func (q *queue[T]) growQueue() {
|
|
desiredLen := (len(q.queue) + 1) * 3 / 2
|
|
if desiredLen < minQueueLen {
|
|
desiredLen = minQueueLen
|
|
}
|
|
|
|
newQueue := make([]T, desiredLen)
|
|
copy(newQueue, q.queue)
|
|
q.queue = newQueue
|
|
}
|