package fifo import ( "cache" "container/list" ) /** * 先进先出缓存 */ type fifo struct { // 缓存最大容量 maxBytes int // 当一个 entry 从缓存中移除时调用该回调函数,默认为 nil onEvicted func(key string, value any) //已使用的字节数,只包括值,key 不算 usedBytes int //缓存容器,存放entry ll *list.List //指针容器 cache map[string]*list.Element } func New(maxBytes int, onEvicted func(key string, value any)) cache.Cache { return &fifo{ maxBytes: maxBytes, onEvicted: onEvicted, ll: list.New(), cache: make(map[string]*list.Element), } } // Set 往 Cache 尾部增加一个元素(如果已经存在,则放入尾部,并修改值) func (f *fifo) Set(key string, value any) { //元素存在 if e, ok := f.cache[key]; ok { f.ll.MoveToBack(e) en := e.Value.(*entry) f.usedBytes = f.usedBytes - cache.CalcLen(en.value) + cache.CalcLen(value) en.value = value } else { en := &entry{key, value} e := f.ll.PushBack(en) f.cache[key] = e f.usedBytes += en.Len() //元素容量校验 if f.CheckOverFlow() { f.DelOldest() } } } // CheckOverFlow 校验容量是否溢出 func (f *fifo) CheckOverFlow() bool { return f.maxBytes > 0 && f.usedBytes > f.maxBytes } func (f *fifo) Get(key string) any { if e, ok := f.cache[key]; ok { return e.Value.(*entry).value } return nil } func (f *fifo) Del(key string) { if e, ok := f.cache[key]; ok { f.removeElement(e) } } func (f *fifo) DelOldest() { //删除列表头部元素 f.removeElement(f.ll.Front()) } func (f *fifo) Len() int { return f.ll.Len() } // removeElement 删除元素 func (f *fifo) removeElement(e *list.Element) { if e == nil { return } f.ll.Remove(e) en := e.Value.(*entry) f.usedBytes -= en.Len() delete(f.cache, en.key) if f.onEvicted != nil { f.onEvicted(en.key, en.value) } } type entry struct { key string value any } func (e *entry) Len() int { return cache.CalcLen(e.value) }