package service import ( "container/list" "sync" ) // lru is a fixed-size map keyed by path, dropping the least recently used entry // when it is full. // // Only use it 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] { // A size below 1 would evict each entry as it is stored, turning the cache // into a silent miss on every lookup. 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) } }