在web程序开发中,个别会应用redis作为数据缓存缓存一些罕用的数据。然而有时候,当访问量特地微小的时候,redis也不肯定能抵御这么大的流量的时候,个别会将罕用的数据放入内存中,避难频繁拜访redis。
因为内存的资源绝对比拟低廉,咱们须要对放入内存中的数据做一些限度以及将一些不罕用的数据清理进来。这个时候就须要用到LRU算法(Least recently used,最近起码应用)。
LSU cache是一种常见的缓存置换算法。会依据缓存拜访的频繁水平,将不罕用的缓存逐步淘汰掉,以开释内存资源。
在go语言中,利用自带的list双向链表能够实现相干算法性能,以下为代码示例
package lru_cacheimport ( "container/list" "sync")type Lrc struct { size int list *list.List cacheMap map[string]*list.Element lock sync.RWMutex}type data struct { key string value interface{}}func NewLrc(size int) *Lrc { return &Lrc{ size: size, list: list.New(), cacheMap: make(map[string]*list.Element), }}// Set 写入缓存func (l *Lrc) Set(key string, value interface{}) { l.lock.Lock() defer l.lock.Unlock() // 判断是否曾经存在 if elem, ok := l.cacheMap[key]; ok { l.list.MoveToFront(elem) elem.Value.(*data).value = value return } item := &data{ key: key, value: value, } elem := l.list.PushFront(item) l.cacheMap[key] = elem // 判断是否超过长度限度 if l.list.Len() > l.size && l.size > 0 { deleteItem := l.list.Back() l.list.Remove(deleteItem) deleteKey := deleteItem.Value.(*data).key delete(l.cacheMap, deleteKey) }}// Get 读取缓存func (l *Lrc) Get(key string) (interface{}, bool) { l.lock.RLock() value, ok := l.cacheMap[key] l.lock.RUnlock() if ok { l.lock.Lock() l.list.MoveToFront(value) l.lock.Unlock() return value.Value.(*data).value, true } else { return nil, false }}// Delete 缓存func (l *Lrc) Delete(key string) { l.lock.RLock() value, ok := l.cacheMap[key] l.lock.RUnlock() if ok { l.lock.Lock() l.list.Remove(value) key := value.Value.(*data).key delete(l.cacheMap, key) l.lock.Unlock() }}
github