mirror of
https://github.com/bloeys/nterm.git
synced 2025-12-29 06:28:20 +00:00
Remove insert/delete from ring+track total written elements to ring
This commit is contained in:
39
ring/ring.go
39
ring/ring.go
@ -9,11 +9,16 @@ type Buffer[T any] struct {
|
||||
Start int64
|
||||
Len int64
|
||||
Cap int64
|
||||
|
||||
// WrittenElements is the total number of elements written to the buffer over its lifetime.
|
||||
// Can be bigger than Cap
|
||||
WrittenElements uint64
|
||||
}
|
||||
|
||||
func (b *Buffer[T]) Write(x ...T) {
|
||||
|
||||
inLen := int64(len(x))
|
||||
b.WrittenElements += uint64(inLen)
|
||||
|
||||
for len(x) > 0 {
|
||||
|
||||
@ -44,40 +49,6 @@ func (b *Buffer[T]) IsFull() bool {
|
||||
return b.Len == b.Cap
|
||||
}
|
||||
|
||||
//Insert inserts the given elements starting at the provided index.
|
||||
//
|
||||
//Note: Insert is a no-op if the buffer is full or doesn't have enough place for the elements
|
||||
func (b *Buffer[T]) Insert(index uint64, x ...T) {
|
||||
|
||||
delta := int64(len(x))
|
||||
newLen := b.Len + delta
|
||||
if newLen > b.Cap {
|
||||
return
|
||||
}
|
||||
|
||||
copy(b.Data[b.Start+int64(index)+delta:], b.Data[index:])
|
||||
copy(b.Data[index:], x)
|
||||
b.Len = newLen
|
||||
}
|
||||
|
||||
//DeleteN removes 'n' elements starting at the provided index.
|
||||
//
|
||||
//Note DeleteN is a no-op if Len==0 or if buffer is full with start>0
|
||||
func (b *Buffer[T]) DeleteN(delStartIndex, n uint64) {
|
||||
|
||||
if b.Len == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if b.Len == b.Cap && b.Start > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
relStartIndex := b.Start + int64(delStartIndex)
|
||||
copy(b.Data[relStartIndex:], b.Data[relStartIndex+int64(n):])
|
||||
b.Len = clamp(b.Len-int64(n), 0, b.Cap)
|
||||
}
|
||||
|
||||
func clamp[T constraints.Ordered](x, min, max T) T {
|
||||
|
||||
if x < min {
|
||||
|
||||
@ -45,50 +45,29 @@ func TestRing(t *testing.T) {
|
||||
b.Write('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i')
|
||||
CheckArr(t, []rune{'i', 'f', 'g', 'h'}, b.Data)
|
||||
|
||||
// Input starting in the middle and having to loop back
|
||||
// Input starting in the middle and having to loop back and WrittenElements
|
||||
b2 := ring.NewBuffer[int](4)
|
||||
Check(t, 0, b2.WrittenElements)
|
||||
|
||||
b2.Write(1, 2, 3)
|
||||
Check(t, 3, b2.WrittenElements)
|
||||
|
||||
b2.Write(4, 5)
|
||||
Check(t, 5, b2.WrittenElements)
|
||||
CheckArr(t, []int{5, 2, 3, 4}, b2.Data)
|
||||
|
||||
b2.Write(6)
|
||||
Check(t, 6, b2.WrittenElements)
|
||||
CheckArr(t, []int{5, 6, 3, 4}, b2.Data)
|
||||
|
||||
b2.Write(7)
|
||||
Check(t, 7, b2.WrittenElements)
|
||||
CheckArr(t, []int{5, 6, 7, 4}, b2.Data)
|
||||
|
||||
b2.Write(8)
|
||||
Check(t, 8, b2.WrittenElements)
|
||||
CheckArr(t, []int{5, 6, 7, 8}, b2.Data)
|
||||
|
||||
// Insert
|
||||
b2 = ring.NewBuffer[int](4)
|
||||
b2.Write(1, 2)
|
||||
|
||||
b2.Insert(0, 3)
|
||||
CheckArr(t, []int{3, 1, 2, 0}, b2.Data)
|
||||
|
||||
b2.Insert(3, 4)
|
||||
CheckArr(t, []int{3, 1, 2, 4}, b2.Data)
|
||||
|
||||
b2.Insert(2, 5, 6)
|
||||
CheckArr(t, []int{3, 1, 2, 4}, b2.Data)
|
||||
|
||||
// Delete
|
||||
b2 = ring.NewBuffer[int](4)
|
||||
b2.Write(1, 2, 3, 4)
|
||||
|
||||
b2.DeleteN(0, 4)
|
||||
Check(t, 0, b2.Start)
|
||||
Check(t, 0, b2.Len)
|
||||
CheckArr(t, []int{1, 2, 3, 4}, b2.Data)
|
||||
|
||||
b2.Write(5, 6, 7, 8)
|
||||
Check(t, 4, b2.Len)
|
||||
b2.DeleteN(2, 1)
|
||||
Check(t, 3, b2.Len)
|
||||
CheckArr(t, []int{5, 6, 8, 8}, b2.Data)
|
||||
|
||||
// ViewsFromTo
|
||||
b2 = ring.NewBuffer[int](4)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user