89 lines
1.8 KiB
Go
89 lines
1.8 KiB
Go
// Copyright 2024 Dolthub, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package circular
|
|
|
|
type Buff[T any] struct {
|
|
// The backing array.
|
|
arr []T
|
|
// Front() and Pop() refer to this element.
|
|
front int
|
|
// The number of elements in the buffer. [0, len(arr)).
|
|
len int
|
|
}
|
|
|
|
func NewBuff[T any](initSz int) *Buff[T] {
|
|
return &Buff[T]{
|
|
arr: make([]T, initSz),
|
|
}
|
|
}
|
|
|
|
// Returns the number of elements currently in Buff.
|
|
func (b *Buff[T]) Len() int {
|
|
return b.len
|
|
}
|
|
|
|
func (b *Buff[T]) Cap() int {
|
|
return cap(b.arr)
|
|
}
|
|
|
|
func (b *Buff[T]) At(i int) T {
|
|
return *b.at(i)
|
|
}
|
|
|
|
func (b *Buff[T]) at(i int) *T {
|
|
if i >= b.Len() {
|
|
panic("At on Buff too small")
|
|
}
|
|
j := (b.front + i) % len(b.arr)
|
|
return &b.arr[j]
|
|
}
|
|
|
|
func (b *Buff[T]) Front() T {
|
|
return b.At(0)
|
|
}
|
|
|
|
func (b *Buff[T]) Pop() {
|
|
if b.Len() == 0 {
|
|
panic("Pop empty Buff")
|
|
}
|
|
// Don't leak entries...
|
|
var empty T
|
|
*b.at(0) = empty
|
|
b.front = (b.front + 1) % len(b.arr)
|
|
b.len -= 1
|
|
}
|
|
|
|
func (b *Buff[T]) ins() int {
|
|
return (b.front + b.len) % len(b.arr)
|
|
}
|
|
|
|
func (b *Buff[T]) Push(t T) {
|
|
if b.Len() == len(b.arr) {
|
|
newarr := make([]T, len(b.arr)+len(b.arr))
|
|
i := b.ins()
|
|
if i > b.front {
|
|
copy(newarr, b.arr[b.front:i])
|
|
} else {
|
|
first := b.arr[b.front:]
|
|
copy(newarr, first)
|
|
copy(newarr[len(first):], b.arr[:i])
|
|
}
|
|
b.arr = newarr
|
|
b.front = 0
|
|
}
|
|
b.arr[b.ins()] = t
|
|
b.len += 1
|
|
}
|