Слияние кода завершено, страница обновится автоматически
package cache
import "container/list"
type lru struct {
// 缓存最大容量,单位字节,这里值最大存放的 元素 的容量,key不算
maxBytes int
// 已使用的字节数,只包括value, key不算
usedBytes int
// 双链表
ll *list.List
// map的key是字符串,value是双链表中对应节点的指针
cache map[string]*list.Element
}
// 创建一个新 Cache,如果 maxBytes 是0,则表示没有容量限制
func NewLruCache(maxBytes int) Cache {
return &fifo{
maxBytes: maxBytes,
ll: list.New(),
cache: make(map[string]*list.Element),
}
}
// 通过 Set 方法往 Cache 头部增加一个元素,如果已经存在,则移到头部,并更新值
func (l *lru) Set(key string, value interface{}) {
if element, ok := l.cache[key]; ok {
// 移动到头部
l.ll.MoveToFront(element)
eVal := element.Value.(*entry)
// 重新计算内存占用
l.usedBytes = l.usedBytes - CalcLen(eVal.value) + CalcLen(value)
// 更新value
element.Value = value
} else {
element := &entry{
key: key,
value: value,
}
e := l.ll.PushFront(element) // 头部插入一个元素并返回该元素
l.cache[key] = e
// 计算内存占用
l.usedBytes += element.Len()
}
// 如果超出内存长度,则删除队首的节点. 0表示无内存限制
for l.maxBytes > 0 && l.maxBytes < l.usedBytes {
l.DelOldest()
}
}
// 获取指定元素(有访问要将该元素移动到头部)
func (l *lru) Get(key string) interface{} {
if e, ok := l.cache[key]; ok {
// 移动到头部
l.ll.MoveToFront(e)
return e.Value.(*entry).value
}
return nil
}
// 删除指定元素
func (l *lru) Del(key string) {
if e, ok := l.cache[key]; ok {
l.removeElement(e)
}
}
// 删除最 '无用' 元素,链表尾部为最无用元素
func (l *lru) DelOldest() {
l.removeElement(l.ll.Back())
}
// 删除元素并更新内存占用大小
func (l *lru) removeElement(e *list.Element) {
if e == nil {
return
}
l.ll.Remove(e)
en := e.Value.(*entry)
l.usedBytes -= en.Len()
delete(l.cache, en.key)
}
// 缓存池元素数量
func (l *lru) Len() int {
return l.ll.Len()
}
// 缓存池已经占用的内存大小
func (l *lru) UseBytes() int {
return l.usedBytes
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )