You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
1.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package lfu
import (
"cache"
"container/heap"
)
// lfu
// @Description:LFU即最少使用也就是淘汰缓存中访问频率最低的记录。
// LFU 认为,如果数据过去被访问多次,那么将来被访问的频率也更高。
// LFU 的实现需要维护一个按照访问次数排序的队列,每次访问,访问次数加 1队列重新排序淘汰时选择访问次数最少的即可
type lfu struct {
// 缓存最大容量
maxBytes int
// 当一个 entry 从缓存中移除时调用该回调函数,默认为 nil
onEvicted func(key string, value any)
//已使用的字节数只包括值key 不算
usedBytes int
queue *queue
cache map[string]*entry
}
func New(maxBytes int, onEvicted func(key string, value any)) cache.Cache {
q := make(queue, 0, 1024)
return &lfu{
maxBytes: maxBytes,
onEvicted: onEvicted,
queue: &q,
cache: make(map[string]*entry),
}
}
func (l *lfu) Set(key string, value any) {
if e, ok := l.cache[key]; ok {
l.usedBytes = l.usedBytes - cache.CalcLen(e.value) + cache.CalcLen(value)
l.queue.update(e, value, e.weight+1)
} else {
en := &entry{key: key, value: value}
//利用堆特性实现排序
heap.Push(l.queue, en)
l.cache[key] = en
l.usedBytes += en.Len()
if l.maxBytes > 0 && l.usedBytes > l.maxBytes {
}
}
}
func (l *lfu) Get(Key string) any {
if e, ok := l.cache[Key]; ok {
l.queue.update(e, e.value, e.weight+1)
return e.value
}
return nil
}
func (l *lfu) Del(Key string) {
if e, ok := l.cache[Key]; ok {
heap.Remove(l.queue, e.index)
}
}
func (l *lfu) DelOldest() {
}
func (l *lfu) Len() int {
return 0
}
func (l *lfu) removeElement(x any) {
if x == nil {
return
}
en := x.(*entry)
delete(l.cache, en.key)
l.usedBytes -= en.Len()
}