1package nightsky23import (4 "gno.land/p/nt/avl/v0"5 "gno.land/p/nt/ufmt/v0"6)78// CaptureFeed is a bounded, newest-first collection of CaptureResult values9// backed by an avl.Tree. It is used for both a single telescope's history and10// the network-wide recent feed.11//12// Entries are keyed by a zero-padded, monotonically increasing sequence so the13// tree iterates in insertion order. Newest-first reads use ReverseIterate, and14// trimming removes the lowest key (the oldest entry). This avoids the O(n)15// slice-prepend the previous implementation paid on every insert, and only16// loads the search path on access instead of the whole collection.17type CaptureFeed struct {18 tree *avl.Tree19 seq int20 max int21}2223// NewCaptureFeed creates a feed that keeps at most max entries.24func NewCaptureFeed(max int) *CaptureFeed {25 if max <= 0 {26 panic("capture feed size must be positive")27 }28 return &CaptureFeed{29 tree: avl.NewTree(),30 seq: 0,31 max: max,32 }33}3435// feedKey renders a sequence into a fixed-width key so that string ordering36// matches numeric ordering.37func feedKey(seq int) string {38 return ufmt.Sprintf("%020d", seq)39}4041// Add inserts a capture as the newest entry and trims the oldest if the feed is42// over capacity.43func (f *CaptureFeed) Add(c CaptureResult) {44 f.seq++45 f.tree.Set(feedKey(f.seq), c)4647 for f.tree.Size() > f.max {48 oldest, _ := f.tree.GetByIndex(0)49 f.tree.Remove(oldest)50 }51}5253// Len returns the number of stored captures.54func (f *CaptureFeed) Len() int {55 return f.tree.Size()56}5758// Latest returns the most recent capture, if any.59func (f *CaptureFeed) Latest() (CaptureResult, bool) {60 if f.tree.Size() == 0 {61 return CaptureResult{}, false62 }63 _, value := f.tree.GetByIndex(f.tree.Size() - 1)64 return value.(CaptureResult), true65}6667// RemoveAt removes the index-th newest capture (0 = most recent). It reports68// whether a capture was removed. Used for moderation of individual entries.69func (f *CaptureFeed) RemoveAt(index int) bool {70 size := f.tree.Size()71 if index < 0 || index >= size {72 return false73 }74 // Newest-first index i maps to ascending-key index (size-1-i).75 key, _ := f.tree.GetByIndex(size - 1 - index)76 _, removed := f.tree.Remove(key)77 return removed78}7980// IterateNewest calls cb for each capture from newest to oldest. Return true81// from cb to stop early.82func (f *CaptureFeed) IterateNewest(cb func(c CaptureResult) bool) {83 f.tree.ReverseIterate("", "", func(_ string, value any) bool {84 return cb(value.(CaptureResult))85 })86}87Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.