shad-go/lrucache/lru.go
2024-06-05 03:46:41 +03:00

69 lines
1.3 KiB
Go

//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()}
}