Files
iroh-tracker/stack/stack.go
T
cblgh 0be552d98f stack: refactor to create + use Keyer interface
refactor Stack to "store an interface" i.e. items []Keyer -> interface Keyer { Key() string }
if storing []Keyer instead, i can store a struct that can contain any number of other fields.
2026-10-16 11:07:18 +02:00

65 lines
1.4 KiB
Go

package stack
type Stack struct {
items []Keyer
}
type Keyer interface {
Key() string
}
func NewStack(size int) *Stack {
s := Stack{items: make([]Keyer, 0, size)}
return &s
}
type EmptyKey struct{}
func (ek EmptyKey) Key() string {
return ""
}
var Empty EmptyKey
// TODO (2026-10-16): look up how to make a proper enumerable / iterable array in golang
// it is apparently relatively recent (2024): https://go.dev/blog/range-functions
func (s* Stack) Items() []Keyer {
return s.items
}
func (s* Stack) Size() int {
return len(s.items)
}
// get evicted item
func (s *Stack) Push (newItem Keyer) Keyer {
if len(s.items) > 0 && s.items[0].Key() == newItem.Key() {
return Empty
}
prev := newItem
for i, elem := range s.items {
// insert newItem at front
if i == 0 {
prev = s.items[0]
s.items[0] = newItem
// newItem was in stack previously, perform in place swap and exit early
} else if elem.Key() == newItem.Key() {
s.items[i] = prev
return Empty
} else {
// propagate change outwards in stack, moving all items one step further
temp := s.items[i]
s.items[i] = prev
prev = temp
}
}
// if we have capacity still, append the last item back onto the end of the staack
if len(s.items) < cap(s.items) {
s.items = append(s.items, prev)
} else {
// we evict the list item, forgetting about it and return the evicted item
return prev
}
return Empty
}