|
|
|
|
@ -10,32 +10,32 @@ import ( |
|
|
|
|
const maxQueuedItems = 16 |
|
|
|
|
|
|
|
|
|
// queue is an ordered queue of length up to maxQueuedItems.
|
|
|
|
|
type queue struct { |
|
|
|
|
vals []any |
|
|
|
|
type queue[T any] struct { |
|
|
|
|
vals []T |
|
|
|
|
start int |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// canAppend reports whether a value can be appended to q.vals without
|
|
|
|
|
// shifting values around.
|
|
|
|
|
func (q *queue) canAppend() bool { |
|
|
|
|
func (q *queue[T]) canAppend() bool { |
|
|
|
|
return cap(q.vals) < maxQueuedItems || len(q.vals) < cap(q.vals) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (q *queue) Full() bool { |
|
|
|
|
func (q *queue[T]) Full() bool { |
|
|
|
|
return q.start == 0 && !q.canAppend() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (q *queue) Empty() bool { |
|
|
|
|
func (q *queue[T]) Empty() bool { |
|
|
|
|
return q.start == len(q.vals) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (q *queue) Len() int { |
|
|
|
|
func (q *queue[T]) Len() int { |
|
|
|
|
return len(q.vals) - q.start |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Add adds v to the end of the queue. Blocks until append can be
|
|
|
|
|
// done.
|
|
|
|
|
func (q *queue) Add(v any) { |
|
|
|
|
func (q *queue[T]) Add(v T) { |
|
|
|
|
if !q.canAppend() { |
|
|
|
|
if q.start == 0 { |
|
|
|
|
panic("Add on a full queue") |
|
|
|
|
@ -54,21 +54,23 @@ func (q *queue) Add(v any) { |
|
|
|
|
|
|
|
|
|
// Peek returns the first value in the queue, without removing it from
|
|
|
|
|
// the queue, or nil if the queue is empty.
|
|
|
|
|
func (q *queue) Peek() any { |
|
|
|
|
func (q *queue[T]) Peek() T { |
|
|
|
|
if q.Empty() { |
|
|
|
|
return nil |
|
|
|
|
var zero T |
|
|
|
|
return zero |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return q.vals[q.start] |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Drop discards the first value in the queue, if any.
|
|
|
|
|
func (q *queue) Drop() { |
|
|
|
|
func (q *queue[T]) Drop() { |
|
|
|
|
if q.Empty() { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
q.vals[q.start] = nil |
|
|
|
|
var zero T |
|
|
|
|
q.vals[q.start] = zero |
|
|
|
|
q.start++ |
|
|
|
|
if q.Empty() { |
|
|
|
|
// Reset cursor to start of array, it's free to do.
|
|
|
|
|
@ -78,6 +80,6 @@ func (q *queue) Drop() { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Snapshot returns a copy of the queue's contents.
|
|
|
|
|
func (q *queue) Snapshot() []any { |
|
|
|
|
func (q *queue[T]) Snapshot() []T { |
|
|
|
|
return slices.Clone(q.vals[q.start:]) |
|
|
|
|
} |
|
|
|
|
|