diff --git a/internal/history/history.go b/internal/history/history.go index 720a611..2077807 100644 --- a/internal/history/history.go +++ b/internal/history/history.go @@ -4,7 +4,7 @@ import "time" // History stores a stack of items, always keeping the bottom-most one. It must // be created using the NewHistory constructor, otherwise it will be invalid. -type History[T any] struct { +type History[T comparable] struct { max int stack []T topIndex int @@ -14,7 +14,7 @@ type History[T any] struct { // NewHistory creates a new History. The initial item will be on the bottom, and // it will remain there until the History overflows and chooses the item after // it to be the initial item. -func NewHistory[T any] (initial T, max int) *History[T] { +func NewHistory[T comparable] (initial T, max int) *History[T] { return &History[T] { max: max, stack: []T { initial }, @@ -29,14 +29,28 @@ func (this *History[T]) Top () T { // Swap replaces the most recent item with another. func (this *History[T]) Swap (item T) { this.topTime = time.Now() + this.SwapSilently(item) +} + +// SwapSilently replaces the most recent item with another without updating the +// time. +func (this *History[T]) SwapSilently (item T) { this.stack[this.topIndex] = item } -// Push pushes a new item onto the stack. +// Push pushes a new item onto the stack. If the stack overflows (becomes bigger +// than the specified max value), the initial item is removed and the one on top +// of it takes its place. func (this *History[T]) Push (item T) { this.topTime = time.Now() - this.topIndex ++ - this.stack = append(this.stack[:this.topIndex], item) + if this.Top() != item { + this.topIndex ++ + this.stack = append(this.stack[:this.topIndex], item) + } + + if len(this.stack) > this.max { + this.stack = this.stack[1:] + } } // PushWeak replaces the most recent item if it was added recently (sooner than