mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-05 10:32:19 +00:00
436493350e
1. changes sentinel to use an http-like interface 2. moves hexutil, crypto/blake2b, metrics packages to erigon-lib
157 lines
2.3 KiB
Go
157 lines
2.3 KiB
Go
package ring
|
|
|
|
type Buffer[T any] struct {
|
|
buf []T
|
|
// real head is head-1, like this so nil ring is valid
|
|
head int
|
|
tail int
|
|
length int
|
|
}
|
|
|
|
func MakeBuffer[T any](length, capacity int) Buffer[T] {
|
|
if length > capacity {
|
|
panic("length must be less than capacity")
|
|
}
|
|
return Buffer[T]{
|
|
buf: make([]T, capacity),
|
|
tail: length,
|
|
length: length,
|
|
}
|
|
}
|
|
|
|
func NewBuffer[T any](length, capacity int) *Buffer[T] {
|
|
r := MakeBuffer[T](length, capacity)
|
|
return &r
|
|
}
|
|
|
|
func (r *Buffer[T]) grow() {
|
|
size := len(r.buf) * 2
|
|
if size == 0 {
|
|
size = 2
|
|
}
|
|
|
|
buf := make([]T, size)
|
|
copy(buf, r.buf[r.head:])
|
|
copy(buf[len(r.buf[r.head:]):], r.buf[:r.head])
|
|
r.head = 0
|
|
r.tail = r.length
|
|
r.buf = buf
|
|
}
|
|
|
|
func (r *Buffer[T]) incHead() {
|
|
// resize
|
|
if r.length == 0 {
|
|
panic("smashing detected")
|
|
}
|
|
r.length--
|
|
|
|
r.head++
|
|
if r.head == len(r.buf) {
|
|
r.head = 0
|
|
}
|
|
}
|
|
|
|
func (r *Buffer[T]) decHead() {
|
|
// resize
|
|
if r.length == len(r.buf) {
|
|
r.grow()
|
|
}
|
|
r.length++
|
|
|
|
r.head--
|
|
if r.head == -1 {
|
|
r.head = len(r.buf) - 1
|
|
}
|
|
}
|
|
|
|
func (r *Buffer[T]) incTail() {
|
|
// resize
|
|
if r.length == len(r.buf) {
|
|
r.grow()
|
|
}
|
|
r.length++
|
|
|
|
r.tail++
|
|
if r.tail == len(r.buf) {
|
|
r.tail = 0
|
|
}
|
|
}
|
|
|
|
func (r *Buffer[T]) decTail() {
|
|
// resize
|
|
if r.length == 0 {
|
|
panic("smashing detected")
|
|
}
|
|
r.length--
|
|
|
|
r.tail--
|
|
if r.tail == -1 {
|
|
r.tail = len(r.buf) - 1
|
|
}
|
|
}
|
|
|
|
func (r *Buffer[T]) tailSub1() int {
|
|
tail := r.tail - 1
|
|
if tail == -1 {
|
|
tail = len(r.buf) - 1
|
|
}
|
|
return tail
|
|
}
|
|
|
|
func (r *Buffer[T]) PopFront() (T, bool) {
|
|
if r.length == 0 {
|
|
return *new(T), false
|
|
}
|
|
|
|
front := r.buf[r.head]
|
|
r.buf[r.head] = *new(T)
|
|
r.incHead()
|
|
return front, true
|
|
}
|
|
|
|
func (r *Buffer[T]) PopBack() (T, bool) {
|
|
if r.length == 0 {
|
|
return *new(T), false
|
|
}
|
|
|
|
r.decTail()
|
|
back := r.buf[r.tail]
|
|
r.buf[r.tail] = *new(T)
|
|
return back, true
|
|
}
|
|
|
|
func (r *Buffer[T]) Clear() {
|
|
r.head = 0
|
|
r.tail = 0
|
|
r.length = 0
|
|
}
|
|
|
|
func (r *Buffer[T]) PushFront(value T) {
|
|
r.decHead()
|
|
r.buf[r.head] = value
|
|
}
|
|
|
|
func (r *Buffer[T]) PushBack(value T) {
|
|
r.incTail()
|
|
r.buf[r.tailSub1()] = value
|
|
}
|
|
|
|
func (r *Buffer[T]) Length() int {
|
|
return r.length
|
|
}
|
|
|
|
func (r *Buffer[T]) Capacity() int {
|
|
return len(r.buf)
|
|
}
|
|
|
|
func (r *Buffer[T]) Get(n int) T {
|
|
if n >= r.length {
|
|
panic("index out of range")
|
|
}
|
|
ptr := r.head + n
|
|
if ptr >= len(r.buf) {
|
|
ptr -= len(r.buf)
|
|
}
|
|
return r.buf[ptr]
|
|
}
|