//go:build !solution package lrucache import ( "container/list" ) type cacheEntry struct { key int value int } type lrucache struct { cap int data map[int]*list.Element recentEntries *list.List } func (c *lrucache) isFull() bool { return c.recentEntries.Len() == c.cap } func (c *lrucache) Get(key int) (int, bool) { e, ok := c.data[key] if !ok { return 0, false } entry := c.recentEntries.Remove(e).(cacheEntry) c.data[key] = c.recentEntries.PushBack(entry) return entry.value, true } func (c *lrucache) Set(key int, value int) { if c.cap == 0 { return } e, ok := c.data[key] if ok { c.recentEntries.Remove(e) c.data[key] = c.recentEntries.PushBack(cacheEntry{key, value}) return } if c.isFull() { removed := c.recentEntries.Remove(c.recentEntries.Front()).(cacheEntry) delete(c.data, removed.key) } c.data[key] = c.recentEntries.PushBack(cacheEntry{key, value}) } func (c *lrucache) Range(f func(key, value int) bool) { for e := c.recentEntries.Front(); e != nil; e = e.Next() { entry := e.Value.(cacheEntry) if !f(entry.key, entry.value) { return } } } func (c *lrucache) Clear() { for k := range c.data { delete(c.data, k) } c.recentEntries.Init() } func New(cap int) Cache { return &lrucache{cap, make(map[int]*list.Element), list.New()} }