package service import ( "container/list" "sync" ) // lru is a fixed-size map keyed by path. Only for values that are safe to lose: // an eviction means the work is redone, never that correctness changes. type lru[V any] struct { mu sync.Mutex maxSize int order *list.List // front is most recently used entries map[string]*list.Element } type lruEntry[V any] struct { key string val V } func newLRU[V any](maxSize int) *lru[V] { // Below 1, each entry is evicted as it is stored: a silent miss every time. return &lru[V]{ maxSize: max(maxSize, 1), order: list.New(), entries: make(map[string]*list.Element), } } func (c *lru[V]) Get(key string) (V, bool) { c.mu.Lock() defer c.mu.Unlock() el, ok := c.entries[key] if !ok { var zero V return zero, false } c.order.MoveToFront(el) return el.Value.(*lruEntry[V]).val, true } func (c *lru[V]) Put(key string, val V) { c.mu.Lock() defer c.mu.Unlock() if el, ok := c.entries[key]; ok { el.Value.(*lruEntry[V]).val = val c.order.MoveToFront(el) return } c.entries[key] = c.order.PushFront(&lruEntry[V]{key: key, val: val}) if c.order.Len() > c.maxSize { oldest := c.order.Back() c.order.Remove(oldest) delete(c.entries, oldest.Value.(*lruEntry[V]).key) } } func (c *lru[V]) Delete(key string) { c.mu.Lock() defer c.mu.Unlock() if el, ok := c.entries[key]; ok { c.order.Remove(el) delete(c.entries, key) } }