package main
import (
"container/list"
"errors"
"sync"
)
type Lru struct {
max int
dataList *list.List
dataMap map[interface{}]*list.Element
rwlock sync.RWMutex
}
type node struct {
key interface{}
value interface{}
}
func NewLru(len int) *Lru {
return &Lru{
max: len,
dataList: list.New(),
dataMap: make(map[interface{}]*list.Element),
}
}
func (l *Lru) Add(key interface{}, val interface{}) error {
l.rwlock.Lock()
defer l.rwlock.Unlock()
if l.dataList == nil {
return errors.New("empyt data list")
}
// 已存在,修改value后移至队首
if e, ok := l.dataMap[key]; ok {
e.Value.(*node).value = val
l.dataList.MoveToFront(e)
return nil
}
// 不存在,在队首插入新结点,在map中存储节点
ele := l.dataList.PushFront(&node{
key: key,
value: val,
})
l.dataMap[key] = ele
// 如果队列超过最大距离,移除队尾的节点,移除map中的key
if l.max != 0 && l.dataList.Len() > l.max {
if e := l.dataList.Back(); e != nil {
l.dataList.Remove(e)
delete(l.dataMap, e.Value.(*node).key)
}
}
return nil
}
func (l *Lru) Remove(key interface{}) bool {
l.rwlock.Lock()
defer l.rwlock.Unlock()
if l.dataList == nil {
return false
}
// 如果存在节点,先移至队首,再返回value
if ele, ok := l.dataMap[key]; ok {
l.dataList.Remove(ele)
delete(l.dataMap, ele.Value.(*node).key)
return true
}
return false
}
func (l *Lru) Get(key interface{}) (val interface{}, ok bool) {
l.rwlock.RLock()
defer l.rwlock.RUnlock()
if l.dataList == nil {
return nil, false
}
// 如果存在节点,先移至队首,再返回value
if ele, ok := l.dataMap[key]; ok {
l.dataList.MoveToFront(ele)
return ele.Value.(*node).value, true
}
return nil, false
}
golang版LRU
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
相关阅读更多精彩内容
- 本文代码已上传github,欢迎交流。 最近在学习go语言,正好有遇到需要使用缓存的地方,于是决定自己造个轮子。主...
- 源码:https://github.com/bluele/gcache[https://github.com/bl...
- 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。实现 LRUCache 类: LR...