nettools/data_structures/cbuf.go

59 lines
1.2 KiB
Go
Raw Normal View History

2024-11-12 12:31:54 +00:00
package dsUtils
2024-11-12 08:10:09 +00:00
2024-11-12 12:31:54 +00:00
// ICBuf is a basic Circular buffer interface
2024-11-12 08:10:09 +00:00
type ICBuf[T any] interface {
Push(item T)
Get() []T
}
2024-11-12 12:31:54 +00:00
// CBuf is the implementation of ICBuf interface
// Simplest circular buffer implementation
2024-11-12 08:10:09 +00:00
// If thread safety is needed -- use CBufSync
2024-11-12 12:31:54 +00:00
//
// WARNING: It's not thread-safe by default,
// use it with a lock
2024-11-12 08:10:09 +00:00
type CBuf[T any] struct {
2024-11-12 12:31:54 +00:00
ICBuf[T]
2024-11-12 08:10:09 +00:00
Buffer []T
Cursor int
Capacity int
}
2024-11-12 12:31:54 +00:00
// NewCBuf creates a new CBuf instance
func NewCBuf[T any](capacity int) *CBuf[T] {
return &CBuf[T]{
Buffer: make([]T, capacity),
Capacity: capacity,
}
}
2024-11-12 08:10:09 +00:00
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
}
2024-11-12 12:31:54 +00:00
// Get returns the whole buffer in the correct order
2024-11-12 08:10:09 +00:00
func (cbuf *CBuf[T]) Get() []T {
2024-11-12 12:31:54 +00:00
out := make([]T, 0, cbuf.Capacity)
copy(out, cbuf.Buffer[cbuf.Cursor:])
out = append(out, cbuf.Buffer[:cbuf.Cursor]...)
return out
2024-11-12 08:10:09 +00:00
}