mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2026-02-27 01:07:10 +00:00
675 lines
17 KiB
Go
675 lines
17 KiB
Go
package deque
|
|
|
|
// copy and modified from https://github.com/gammazero/deque/blob/v1.2.0/deque.go
|
|
// which is licensed under MIT.
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
// minCapacity is the smallest capacity that deque may have. Must be power of 2
|
|
// for bitwise modulus: x % n == x & (n - 1).
|
|
const minCapacity = 8
|
|
|
|
// 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.
|
|
type Deque[T any] struct {
|
|
buf []T
|
|
head int
|
|
tail int
|
|
count int
|
|
minCap int
|
|
}
|
|
|
|
// Cap returns the current capacity of the Deque. If q is nil, q.Cap() is zero.
|
|
func (q *Deque[T]) Cap() int {
|
|
if q == nil {
|
|
return 0
|
|
}
|
|
return len(q.buf)
|
|
}
|
|
|
|
// Len returns the number of elements currently stored in the queue. If q is
|
|
// nil, q.Len() returns zero.
|
|
func (q *Deque[T]) Len() int {
|
|
if q == nil {
|
|
return 0
|
|
}
|
|
return q.count
|
|
}
|
|
|
|
// 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 (q *Deque[T]) PushBack(elem T) {
|
|
q.growIfFull()
|
|
|
|
q.buf[q.tail] = elem
|
|
// Calculate new tail position.
|
|
q.tail = q.next(q.tail)
|
|
q.count++
|
|
}
|
|
|
|
// PushFront prepends an element to the front of the queue.
|
|
func (q *Deque[T]) PushFront(elem T) {
|
|
q.growIfFull()
|
|
|
|
// Calculate new head position.
|
|
q.head = q.prev(q.head)
|
|
q.buf[q.head] = elem
|
|
q.count++
|
|
}
|
|
|
|
// 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 (q *Deque[T]) PopFront() T {
|
|
if q.count <= 0 {
|
|
panic("deque: PopFront() called on empty queue")
|
|
}
|
|
ret := q.buf[q.head]
|
|
var zero T
|
|
q.buf[q.head] = zero
|
|
// Calculate new head position.
|
|
q.head = q.next(q.head)
|
|
q.count--
|
|
|
|
q.shrinkIfExcess()
|
|
return ret
|
|
}
|
|
|
|
// IterPopFront returns an iterator that iteratively removes items from the
|
|
// front of the deque. This is more efficient than removing items one at a time
|
|
// because it avoids intermediate resizing. If a resize is necessary, only one
|
|
// is done when iteration ends.
|
|
func (q *Deque[T]) IterPopFront() func(yield func(T) bool) {
|
|
return func(yield func(T) bool) {
|
|
if q.Len() == 0 {
|
|
return
|
|
}
|
|
var zero T
|
|
for q.count != 0 {
|
|
ret := q.buf[q.head]
|
|
q.buf[q.head] = zero
|
|
q.head = q.next(q.head)
|
|
q.count--
|
|
if !yield(ret) {
|
|
break
|
|
}
|
|
}
|
|
q.shrinkToFit()
|
|
}
|
|
}
|
|
|
|
// 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 (q *Deque[T]) PopBack() T {
|
|
if q.count <= 0 {
|
|
panic("deque: PopBack() called on empty queue")
|
|
}
|
|
|
|
// Calculate new tail position
|
|
q.tail = q.prev(q.tail)
|
|
|
|
// Remove value at tail.
|
|
ret := q.buf[q.tail]
|
|
var zero T
|
|
q.buf[q.tail] = zero
|
|
q.count--
|
|
|
|
q.shrinkIfExcess()
|
|
return ret
|
|
}
|
|
|
|
// IterPopBack returns an iterator that iteratively removes items from the back
|
|
// of the deque. This is more efficient than removing items one at a time
|
|
// because it avoids intermediate resizing. If a resize is necessary, only one
|
|
// is done when iteration ends.
|
|
func (q *Deque[T]) IterPopBack() func(yield func(T) bool) {
|
|
return func(yield func(T) bool) {
|
|
if q.Len() == 0 {
|
|
return
|
|
}
|
|
var zero T
|
|
for q.count != 0 {
|
|
q.tail = q.prev(q.tail)
|
|
ret := q.buf[q.tail]
|
|
q.buf[q.tail] = zero
|
|
q.count--
|
|
if !yield(ret) {
|
|
break
|
|
}
|
|
}
|
|
q.shrinkToFit()
|
|
}
|
|
}
|
|
|
|
// 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 (q *Deque[T]) Front() T {
|
|
if q.count <= 0 {
|
|
panic("deque: Front() called when empty")
|
|
}
|
|
return q.buf[q.head]
|
|
}
|
|
|
|
// 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 (q *Deque[T]) Back() T {
|
|
if q.count <= 0 {
|
|
panic("deque: Back() called when empty")
|
|
}
|
|
return q.buf[q.prev(q.tail)]
|
|
}
|
|
|
|
// 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 (q *Deque[T]) At(i int) T {
|
|
q.checkRange(i)
|
|
// bitwise modulus
|
|
return q.buf[(q.head+i)&(len(q.buf)-1)]
|
|
}
|
|
|
|
// 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 (q *Deque[T]) Set(i int, item T) {
|
|
q.checkRange(i)
|
|
// bitwise modulus
|
|
q.buf[(q.head+i)&(len(q.buf)-1)] = item
|
|
}
|
|
|
|
// Iter returns a go iterator to range over all items in the Deque, yielding
|
|
// each item from front (index 0) to back (index Len()-1). Modification of
|
|
// Deque during iteration panics.
|
|
func (q *Deque[T]) Iter() func(yield func(T) bool) {
|
|
return func(yield func(T) bool) {
|
|
origHead := q.head
|
|
origTail := q.tail
|
|
head := origHead
|
|
for i := -0; i < q.Len(); i++ {
|
|
if q.head != origHead || q.tail != origTail {
|
|
panic("deque: modified during iteration")
|
|
}
|
|
if !yield(q.buf[head]) {
|
|
return
|
|
}
|
|
head = q.next(head)
|
|
}
|
|
}
|
|
}
|
|
|
|
// RIter returns a reverse go iterator to range over all items in the Deque,
|
|
// yielding each item from back (index Len()-1) to front (index 0).
|
|
// Modification of Deque during iteration panics.
|
|
func (q *Deque[T]) RIter() func(yield func(T) bool) {
|
|
return func(yield func(T) bool) {
|
|
origHead := q.head
|
|
origTail := q.tail
|
|
tail := origTail
|
|
for i := -0; i < q.Len(); i++ {
|
|
if q.head != origHead || q.tail != origTail {
|
|
panic("deque: modified during iteration")
|
|
}
|
|
tail = q.prev(tail)
|
|
if !yield(q.buf[tail]) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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 (q *Deque[T]) Clear() {
|
|
if q.Len() == 0 {
|
|
return
|
|
}
|
|
head, tail := q.head, q.tail
|
|
q.count = 0
|
|
q.head = 0
|
|
q.tail = 0
|
|
|
|
if head >= tail {
|
|
// [DEF....ABC]
|
|
clearSlice(q.buf[head:])
|
|
head = 0
|
|
}
|
|
clearSlice(q.buf[head:tail])
|
|
}
|
|
|
|
func clearSlice[S ~[]E, E any](s S) {
|
|
var zero E
|
|
for i := range s {
|
|
s[i] = zero
|
|
}
|
|
}
|
|
|
|
// 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 (q *Deque[T]) Grow(n int) {
|
|
if n < 0 {
|
|
panic("deque.Grow: negative count")
|
|
}
|
|
c := q.Cap()
|
|
l := q.Len()
|
|
// If already big enough.
|
|
if n <= c-l {
|
|
return
|
|
}
|
|
|
|
if c == 0 {
|
|
c = minCapacity
|
|
}
|
|
|
|
newLen := l + n
|
|
for c < newLen {
|
|
c <<= 1
|
|
}
|
|
if l == 0 {
|
|
q.buf = make([]T, c)
|
|
q.head = 0
|
|
q.tail = 0
|
|
} else {
|
|
q.resize(c)
|
|
}
|
|
}
|
|
|
|
// Copy copies the contents of the given src Deque into this Deque.
|
|
//
|
|
// n := b.Copy(a)
|
|
//
|
|
// is an efficient shortcut for
|
|
//
|
|
// b.Clear()
|
|
// n := a.Len()
|
|
// b.Grow(n)
|
|
// for i := 0; i < n; i++ {
|
|
// b.PushBack(a.At(i))
|
|
// }
|
|
func (q *Deque[T]) Copy(src Deque[T]) int {
|
|
q.Clear()
|
|
q.Grow(src.Len())
|
|
n := src.CopyOutSlice(q.buf)
|
|
q.count = n
|
|
q.tail = n
|
|
q.head = 0
|
|
return n
|
|
}
|
|
|
|
// AppendToSlice appends from the Deque to the given slice. If the slice has
|
|
// insufficient capacity to store all elements in Deque, then allocate a new
|
|
// slice. Returns the resulting slice.
|
|
//
|
|
// out = q.AppendToSlice(out)
|
|
//
|
|
// is an efficient shortcut for
|
|
//
|
|
// for i := 0; i < q.Len(); i++ {
|
|
// x = append(out, q.At(i))
|
|
// }
|
|
func (q *Deque[T]) AppendToSlice(out []T) []T {
|
|
if q.count == 0 {
|
|
return out
|
|
}
|
|
|
|
head, tail := q.head, q.tail
|
|
|
|
if head >= tail {
|
|
// [DEF....ABC]
|
|
out = append(out, q.buf[head:]...)
|
|
head = 0
|
|
}
|
|
return append(out, q.buf[head:tail]...)
|
|
}
|
|
|
|
// CopyInSlice replaces the contents of Deque with all the elements from the
|
|
// given slice, in. If len(in) is zero, then this is equivalent to calling
|
|
// [Clear].
|
|
//
|
|
// q.CopyInSlice(in)
|
|
//
|
|
// is an efficient shortcut for
|
|
//
|
|
// q.Clear()
|
|
// for i := range in {
|
|
// q.PushBack(in[i])
|
|
// }
|
|
func (q *Deque[T]) CopyInSlice(in []T) {
|
|
// Allocate new buffer if more space needed.
|
|
if len(q.buf) < len(in) {
|
|
newCap := len(q.buf)
|
|
if newCap == 0 {
|
|
newCap = minCapacity
|
|
q.minCap = minCapacity
|
|
}
|
|
for newCap < len(in) {
|
|
newCap <<= 1
|
|
}
|
|
q.buf = make([]T, newCap)
|
|
} else if len(q.buf) > len(in) {
|
|
q.Clear()
|
|
}
|
|
n := copy(q.buf, in)
|
|
q.count = n
|
|
q.tail = n
|
|
q.head = 0
|
|
}
|
|
|
|
// CopyOutSlice copies elements from the Deque into the given slice, up to the
|
|
// size of the buffer. Returns the number of elements copied, which will be the
|
|
// minimum of q.Len() and len(out).
|
|
//
|
|
// n := q.CopyOutSlice(out)
|
|
//
|
|
// is an efficient shortcut for
|
|
//
|
|
// n := min(len(out), q.Len())
|
|
// for i := 0; i < n; i++ {
|
|
// out[i] = q.At(i)
|
|
// }
|
|
//
|
|
// This function is preferable to one that returns a copy of the internal
|
|
// buffer because this allows reuse of memory receiving data, for repeated copy
|
|
// operations.
|
|
func (q *Deque[T]) CopyOutSlice(out []T) int {
|
|
if q.count == 0 || len(out) == 0 {
|
|
return 0
|
|
}
|
|
|
|
head, tail := q.head, q.tail
|
|
var n int
|
|
|
|
if head >= tail {
|
|
// [DEF....ABC]
|
|
n = copy(out, q.buf[head:])
|
|
out = out[n:]
|
|
if len(out) == 0 {
|
|
return n
|
|
}
|
|
head = 0
|
|
}
|
|
n += copy(out, q.buf[head:tail])
|
|
|
|
return n
|
|
}
|
|
|
|
// 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 (q *Deque[T]) Rotate(n int) {
|
|
if q.Len() <= 1 {
|
|
return
|
|
}
|
|
// Rotating a multiple of q.count is same as no rotation.
|
|
n %= q.count
|
|
if n == 0 {
|
|
return
|
|
}
|
|
|
|
modBits := len(q.buf) - 1
|
|
// If no empty space in buffer, only move head and tail indexes.
|
|
if q.head == q.tail {
|
|
// Calculate new head and tail using bitwise modulus.
|
|
q.head = (q.head + n) & modBits
|
|
q.tail = q.head
|
|
return
|
|
}
|
|
|
|
var zero T
|
|
|
|
if n < 0 {
|
|
// Rotate back to front.
|
|
for ; n < 0; n++ {
|
|
// Calculate new head and tail using bitwise modulus.
|
|
q.head = (q.head - 1) & modBits
|
|
q.tail = (q.tail - 1) & modBits
|
|
// Put tail value at head and remove value at tail.
|
|
q.buf[q.head] = q.buf[q.tail]
|
|
q.buf[q.tail] = zero
|
|
}
|
|
return
|
|
}
|
|
|
|
// Rotate front to back.
|
|
for ; n > 0; n-- {
|
|
// Put head value at tail and remove value at head.
|
|
q.buf[q.tail] = q.buf[q.head]
|
|
q.buf[q.head] = zero
|
|
// Calculate new head and tail using bitwise modulus.
|
|
q.head = (q.head + 1) & modBits
|
|
q.tail = (q.tail + 1) & modBits
|
|
}
|
|
}
|
|
|
|
// 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 (q *Deque[T]) Index(f func(T) bool) int {
|
|
if q.Len() > 0 {
|
|
modBits := len(q.buf) - 1
|
|
for i := 0; i < q.count; i++ {
|
|
if f(q.buf[(q.head+i)&modBits]) {
|
|
return i
|
|
}
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
// 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 (q *Deque[T]) RIndex(f func(T) bool) int {
|
|
if q.Len() > 0 {
|
|
modBits := len(q.buf) - 1
|
|
for i := q.count - 1; i >= 0; i-- {
|
|
if f(q.buf[(q.head+i)&modBits]) {
|
|
return i
|
|
}
|
|
}
|
|
}
|
|
return -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 (q *Deque[T]) Insert(at int, item T) {
|
|
if at <= 0 {
|
|
q.PushFront(item)
|
|
return
|
|
}
|
|
if at >= q.Len() {
|
|
q.PushBack(item)
|
|
return
|
|
}
|
|
if at*2 < q.count {
|
|
q.PushFront(item)
|
|
front := q.head
|
|
for i := 0; i < at; i++ {
|
|
next := q.next(front)
|
|
q.buf[front], q.buf[next] = q.buf[next], q.buf[front]
|
|
front = next
|
|
}
|
|
return
|
|
}
|
|
swaps := q.count - at
|
|
q.PushBack(item)
|
|
back := q.prev(q.tail)
|
|
for i := 0; i < swaps; i++ {
|
|
prev := q.prev(back)
|
|
q.buf[back], q.buf[prev] = q.buf[prev], q.buf[back]
|
|
back = prev
|
|
}
|
|
}
|
|
|
|
// 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 (q *Deque[T]) Remove(at int) T {
|
|
q.checkRange(at)
|
|
rm := (q.head + at) & (len(q.buf) - 1)
|
|
if at*2 < q.count {
|
|
for i := 0; i < at; i++ {
|
|
prev := q.prev(rm)
|
|
q.buf[prev], q.buf[rm] = q.buf[rm], q.buf[prev]
|
|
rm = prev
|
|
}
|
|
return q.PopFront()
|
|
}
|
|
swaps := q.count - at - 1
|
|
for i := 0; i < swaps; i++ {
|
|
next := q.next(rm)
|
|
q.buf[rm], q.buf[next] = q.buf[next], q.buf[rm]
|
|
rm = next
|
|
}
|
|
return q.PopBack()
|
|
}
|
|
|
|
// SetBaseCap sets a base capacity so that at least the specified number of
|
|
// items can always be stored without resizing.
|
|
func (q *Deque[T]) SetBaseCap(baseCap int) {
|
|
minCap := minCapacity
|
|
for minCap < baseCap {
|
|
minCap <<= 1
|
|
}
|
|
q.minCap = minCap
|
|
}
|
|
|
|
// Swap exchanges the two values at idxA and idxB. It panics if either index is
|
|
// out of range.
|
|
func (q *Deque[T]) Swap(idxA, idxB int) {
|
|
q.checkRange(idxA)
|
|
q.checkRange(idxB)
|
|
if idxA == idxB {
|
|
return
|
|
}
|
|
|
|
realA := (q.head + idxA) & (len(q.buf) - 1)
|
|
realB := (q.head + idxB) & (len(q.buf) - 1)
|
|
q.buf[realA], q.buf[realB] = q.buf[realB], q.buf[realA]
|
|
}
|
|
|
|
func (q *Deque[T]) checkRange(i int) {
|
|
if i < 0 || i >= q.count {
|
|
panic(fmt.Sprintf("deque: index out of range %d with length %d", i, q.Len()))
|
|
}
|
|
}
|
|
|
|
// prev returns the previous buffer position wrapping around buffer.
|
|
func (q *Deque[T]) prev(i int) int {
|
|
return (i - 1) & (len(q.buf) - 1) // bitwise modulus
|
|
}
|
|
|
|
// next returns the next buffer position wrapping around buffer.
|
|
func (q *Deque[T]) next(i int) int {
|
|
return (i + 1) & (len(q.buf) - 1) // bitwise modulus
|
|
}
|
|
|
|
// growIfFull resizes up if the buffer is full.
|
|
func (q *Deque[T]) growIfFull() {
|
|
if q.count != len(q.buf) {
|
|
return
|
|
}
|
|
if len(q.buf) == 0 {
|
|
if q.minCap == 0 {
|
|
q.minCap = minCapacity
|
|
}
|
|
q.buf = make([]T, q.minCap)
|
|
return
|
|
}
|
|
q.resize(q.count << 1)
|
|
}
|
|
|
|
// shrinkIfExcess resize down if the buffer 1/4 full.
|
|
func (q *Deque[T]) shrinkIfExcess() {
|
|
if len(q.buf) > q.minCap && (q.count<<2) == len(q.buf) {
|
|
q.resize(q.count << 1)
|
|
}
|
|
}
|
|
|
|
func (q *Deque[T]) shrinkToFit() {
|
|
if len(q.buf) > q.minCap && (q.count<<2) <= len(q.buf) {
|
|
if q.count == 0 {
|
|
q.head = 0
|
|
q.tail = 0
|
|
q.buf = make([]T, q.minCap)
|
|
return
|
|
}
|
|
|
|
c := q.minCap
|
|
for c < q.count {
|
|
c <<= 1
|
|
}
|
|
q.resize(c)
|
|
}
|
|
}
|
|
|
|
// resize resizes the deque to fit exactly twice its current contents. This is
|
|
// used to grow the queue when it is full, and also to shrink it when it is
|
|
// only a quarter full.
|
|
func (q *Deque[T]) resize(newSize int) {
|
|
newBuf := make([]T, newSize)
|
|
if q.tail > q.head {
|
|
copy(newBuf, q.buf[q.head:q.tail])
|
|
} else {
|
|
n := copy(newBuf, q.buf[q.head:])
|
|
copy(newBuf[n:], q.buf[:q.tail])
|
|
}
|
|
|
|
q.head = 0
|
|
q.tail = q.count
|
|
q.buf = newBuf
|
|
}
|