Documentation
¶
Overview ¶
Package deque provides a fast ring-buffer deque (double-ended queue) implementation.
Deque generalizes a queue and a stack, to efficiently add and remove items at either end with O(1) performance. Queue (FIFO) operations are supported using PushBack and PopFront. Stack (LIFO) operations are supported using PushBack and PopBack.
Ring-buffer Performance ¶
The ring-buffer automatically resizes by powers of two, growing when additional capacity is needed and shrinking when only a quarter of the capacity is used, and uses bitwise arithmetic for all calculations.
The ring-buffer implementation significantly improves memory and time performance with fewer GC pauses, compared to implementations based on slices and linked lists.
For maximum speed, this deque implementation leaves concurrency safety up to the application to provide, however the application chooses, if needed at all.
Reading Empty Deque ¶
Since it is OK for the deque to contain the zero-value of an item, it is necessary to either panic or return a second boolean value to indicate the deque is empty, when reading or removing an element. This deque panics when reading from an empty deque. This is a run-time check to help catch programming errors, which may be missed if a second return value is ignored. Simply check Deque.Len() before reading from the deque.
Generics ¶
Deque uses generics to create a Deque that contains items of the type specified. To create a Deque that holds a specific type, provide a type argument with the Deque variable declaration.
Index ¶
- type Deque
- func (q *Deque[T]) At(i int) T
- func (q *Deque[T]) Back() T
- func (q *Deque[T]) Cap() int
- func (q *Deque[T]) Clear()
- func (q *Deque[T]) Front() T
- func (q *Deque[T]) Grow(n int)
- func (q *Deque[T]) Index(f func(T) bool) int
- func (q *Deque[T]) Insert(at int, item T)
- func (q *Deque[T]) Len() int
- func (q *Deque[T]) PopBack() T
- func (q *Deque[T]) PopFront() T
- func (q *Deque[T]) PushBack(elem T)
- func (q *Deque[T]) PushFront(elem T)
- func (q *Deque[T]) RIndex(f func(T) bool) int
- func (q *Deque[T]) Remove(at int) T
- func (q *Deque[T]) Rotate(n int)
- func (q *Deque[T]) Set(i int, item T)
- func (q *Deque[T]) SetBaseCap(baseCap int)
- func (q *Deque[T]) Swap(idxA, idxB int)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Deque ¶
type Deque[T any] struct { // contains filtered or unexported fields }
Deque represents a single instance of the deque data structure. A Deque instance contains items of the type specified by the type argument.
For example, to create a Deque that contains strings do one of the following:
var stringDeque deque.Deque[string] stringDeque := new(deque.Deque[string]) stringDeque := &deque.Deque[string]{}
To create a Deque that will never resize to have space for less than 64 items, specify a base capacity:
var d deque.Deque[int] d.SetBaseCap(64)
To ensure the Deque can store 1000 items without needing to resize while items are added:
d.Grow(1000)
Any values supplied to SetBaseCap and Grow are rounded up to the nearest power of 2, since the Deque grows by powers of 2.
func (*Deque[T]) At ¶
At returns the element at index i in the queue without removing the element from the queue. This method accepts only non-negative index values. At(0) refers to the first element and is the same as Front(). At(Len()-1) refers to the last element and is the same as Back(). If the index is invalid, the call panics.
The purpose of At is to allow Deque to serve as a more general purpose circular buffer, where items are only added to and removed from the ends of the deque, but may be read from any place within the deque. Consider the case of a fixed-size circular log buffer: A new entry is pushed onto one end and when full the oldest is popped from the other end. All the log entries in the buffer must be readable without altering the buffer contents.
func (*Deque[T]) Back ¶
func (q *Deque[T]) Back() T
Back returns the element at the back of the queue. This is the element that would be returned by PopBack. This call panics if the queue is empty.
func (*Deque[T]) Clear ¶
func (q *Deque[T]) Clear()
Clear removes all elements from the queue, but retains the current capacity. This is useful when repeatedly reusing the queue at high frequency to avoid GC during reuse. The queue will not be resized smaller as long as items are only added. Only when items are removed is the queue subject to getting resized smaller.
func (*Deque[T]) Front ¶
func (q *Deque[T]) Front() T
Front returns the element at the front of the queue. This is the element that would be returned by PopFront. This call panics if the queue is empty.
func (*Deque[T]) Grow ¶ added in v1.0.0
Grow grows deque's capacity, if necessary, to guarantee space for another n items. After Grow(n), at least n items can be written to the deque without another allocation. If n is negative, Grow panics.
func (*Deque[T]) Index ¶ added in v0.1.1
Index returns the index into the Deque of the first item satisfying f(item), or -1 if none do. If q is nil, then -1 is always returned. Search is linear starting with index 0.
func (*Deque[T]) Insert ¶ added in v0.1.1
Insert is used to insert an element into the middle of the queue, before the element at the specified index. Insert(0,e) is the same as PushFront(e) and Insert(Len(),e) is the same as PushBack(e). Out of range indexes result in pushing the item onto the front of back of the deque.
Important: Deque is optimized for O(1) operations at the ends of the queue, not for operations in the the middle. Complexity of this function is constant plus linear in the lesser of the distances between the index and either of the ends of the queue.
func (*Deque[T]) Len ¶
Len returns the number of elements currently stored in the queue. If q is nil, q.Len() returns zero.
func (*Deque[T]) PopBack ¶
func (q *Deque[T]) PopBack() T
PopBack removes and returns the element from the back of the queue. Implements LIFO when used with PushBack. If the queue is empty, the call panics.
func (*Deque[T]) PopFront ¶
func (q *Deque[T]) PopFront() T
PopFront removes and returns the element from the front of the queue. Implements FIFO when used with PushBack. If the queue is empty, the call panics.
func (*Deque[T]) PushBack ¶
func (q *Deque[T]) PushBack(elem T)
PushBack appends an element to the back of the queue. Implements FIFO when elements are removed with PopFront, and LIFO when elements are removed with PopBack.
func (*Deque[T]) PushFront ¶
func (q *Deque[T]) PushFront(elem T)
PushFront prepends an element to the front of the queue.
func (*Deque[T]) RIndex ¶ added in v0.1.2
RIndex is the same as Index, but searches from Back to Front. The index returned is from Front to Back, where index 0 is the index of the item returned by Front().
func (*Deque[T]) Remove ¶ added in v0.1.1
Remove removes and returns an element from the middle of the queue, at the specified index. Remove(0) is the same as PopFront() and Remove(Len()-1) is the same as PopBack(). Accepts only non-negative index values, and panics if index is out of range.
Important: Deque is optimized for O(1) operations at the ends of the queue, not for operations in the the middle. Complexity of this function is constant plus linear in the lesser of the distances between the index and either of the ends of the queue.
func (*Deque[T]) Rotate ¶
Rotate rotates the deque n steps front-to-back. If n is negative, rotates back-to-front. Having Deque provide Rotate avoids resizing that could happen if implementing rotation using only Pop and Push methods. If q.Len() is one or less, or q is nil, then Rotate does nothing.
func (*Deque[T]) Set ¶
Set assigns the item to index i in the queue. Set indexes the deque the same as At but perform the opposite operation. If the index is invalid, the call panics.
func (*Deque[T]) SetBaseCap ¶ added in v1.0.0
SetBaseCap sets a base capacity so that at least the specified number of items can always be stored without resizing.