2024-11-12 10:08:08 +00:00
|
|
|
package dbUtils
|
2024-11-12 08:10:09 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Basic Circular buffer interface
|
|
|
|
type ICBuf[T any] interface {
|
|
|
|
Push(item T)
|
|
|
|
Get() []T
|
|
|
|
}
|
|
|
|
|
|
|
|
// Implementation of ICBuf interface
|
|
|
|
// Simpliest circular buffer implementation
|
|
|
|
// If thread safety is needed -- use CBufSync
|
|
|
|
type CBuf[T any] struct {
|
|
|
|
Buffer []T
|
|
|
|
Cursor int
|
|
|
|
Capacity int
|
|
|
|
}
|
|
|
|
|
|
|
|
// Same as pushing back to array
|
|
|
|
func (cbuf *CBuf[T]) Push(item T) {
|
|
|
|
cbuf.Buffer[cbuf.Cursor] = item
|
|
|
|
cbuf.Cursor++
|
|
|
|
if cbuf.Cursor >= cbuf.Capacity {
|
|
|
|
cbuf.Cursor = 0
|
|
|
|
}
|
|
|
|
println(cbuf.Cursor)
|
|
|
|
}
|
|
|
|
|
|
|
|
// This method isn't a part of ICBuf interface
|
|
|
|
//
|
|
|
|
// It pushes item to the "buffer start"
|
|
|
|
// (Right before the cursor)
|
|
|
|
// removing item from back
|
|
|
|
func (cbuf *CBuf[T]) PushFront(item T) {
|
|
|
|
cbuf.Buffer = append(
|
|
|
|
append(cbuf.Buffer[cbuf.Cursor+1:], cbuf.Buffer[:cbuf.Cursor]...),
|
|
|
|
item,
|
|
|
|
)
|
|
|
|
cbuf.Cursor = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
// Just returning the whole buffer in the correct order
|
|
|
|
func (cbuf *CBuf[T]) Get() []T {
|
|
|
|
return append(cbuf.Buffer[cbuf.Cursor:], cbuf.Buffer[:cbuf.Cursor]...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewCBuf[T any](capacity int) *CBuf[T] {
|
|
|
|
return &CBuf[T]{
|
|
|
|
Buffer: make([]T, capacity),
|
|
|
|
Capacity: capacity,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Same CBuf, but with mutex
|
|
|
|
type CBufSync[T any] struct {
|
|
|
|
Buffer []T
|
|
|
|
Cursor int
|
|
|
|
Capacity int
|
|
|
|
Mu *sync.RWMutex
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewCBufSync[T any](capacity int) *CBufSync[T] {
|
|
|
|
return &CBufSync[T]{
|
|
|
|
Mu: &sync.RWMutex{},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cbuf *CBufSync[T]) Push(item T) {
|
|
|
|
cbuf.Mu.Lock()
|
|
|
|
cbuf.Buffer[cbuf.Cursor] = item
|
|
|
|
cbuf.Cursor++
|
|
|
|
if cbuf.Cursor >= cbuf.Capacity {
|
|
|
|
cbuf.Cursor = 0
|
|
|
|
}
|
|
|
|
cbuf.Mu.Unlock()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cbuf *CBufSync[T]) PushFront(item T) {
|
|
|
|
cbuf.Mu.Lock()
|
|
|
|
cbuf.Buffer = append(
|
|
|
|
append(cbuf.Buffer[cbuf.Cursor+1:], cbuf.Buffer[:cbuf.Cursor]...),
|
|
|
|
item,
|
|
|
|
)
|
|
|
|
cbuf.Cursor = 0
|
|
|
|
cbuf.Mu.Unlock()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cbuf *CBufSync[T]) Get() []T {
|
|
|
|
cbuf.Mu.RLock()
|
|
|
|
defer cbuf.Mu.RUnlock()
|
|
|
|
return append(cbuf.Buffer[cbuf.Cursor:], cbuf.Buffer[:cbuf.Cursor]...)
|
|
|
|
}
|