banner
RustyNail

RustyNail

coder. 【blog】https://rustynail.me 【nostr】wss://ts.relays.world/ wss://relays.world/nostr

LruCache「Golang实现」

LRU 缓存「Golang 实现」

LRU 的应用场景非常广,只要有缓存需求的地方基本都有它的影子。 从内存分页置换算法、redis 的 key 维护等。

LRU 的结构相对简单,为了位置 O(1)的效率,使用了双向链表和哈希表来储存数据

package lru

type Node struct {
	Key   string
	Value interface{}

	Pre *Node
	Suf *Node
}

type DLink struct {
	Len int

	Head *Node
	Tail *Node
}

func NewDLink() *DLink {
	dl := &DLink{
		Len:  0,
		Head: &Node{},
		Tail: &Node{},
	}
	dl.Head.Suf = dl.Tail
	dl.Tail.Pre = dl.Head
	return dl
}

func (dl *DLink) Show() {
	curr := dl.Head
	for curr != dl.Tail {
		print(curr.Key, ",")
		curr = curr.Suf
	}
	println("\n------------")
}

func (lc *LruCache) Show() {
	lc.link.Show()
}

func (dl *DLink) addLast(n *Node) {
	n.Pre = dl.Tail.Pre
	n.Suf = dl.Tail
	dl.Tail.Pre.Suf = n
	dl.Tail.Pre = n
	dl.Len++
}

func (dl *DLink) remove(n *Node) {
	n.Suf.Pre = n.Pre
	n.Pre.Suf = n.Suf
	dl.Len--
}

func (dl *DLink) removeFirst() *Node {
	if dl.Head.Suf == dl.Tail {
		return nil
	}
	first := dl.Head.Suf
	dl.remove(first)
	dl.Len--
	return first
}

func (lc *LruCache) makeFirst(key string) {
	lc.link.remove(lc.CacheMap[key])
	lc.link.addLast(lc.CacheMap[key])
}

func (lc *LruCache) recent(key string, value interface{}) {
	n := &Node{
		Key:   key,
		Value: value,
	}
	lc.link.addLast(n)
	lc.CacheMap[key] = n
}

func (lc *LruCache) deleteKey(key string) {
	lc.link.remove(lc.CacheMap[key])
	lc.CacheMap[key] = nil
}

func (lc *LruCache) removeLRU() {
	f := lc.link.removeFirst()
	lc.CacheMap[f.Key] = nil
}

func (lc *LruCache) Put(key string, value interface{}) {
	temp := lc.CacheMap[key]
	if temp != nil {
		temp.Value = value
		lc.makeFirst(temp.Key)
	} else {
		if lc.MaxSize == lc.link.Len {
			lc.removeLRU()
		}
		n := &Node{
			Key:   key,
			Value: value,
		}
		lc.link.addLast(n)
		lc.CacheMap[key] = n
	}
}

func (lc *LruCache) Get(key string) interface{} {
	lc.makeFirst(key)
	return lc.CacheMap[key].Value
}

func New(maxSize int) *LruCache {
	return &LruCache{
		MaxSize:  maxSize,
		CacheMap: make(map[string]*Node, maxSize),
		link:     NewDLink(),
	}
}

type LruCache struct {
	MaxSize int

	CacheMap map[string]*Node
	link     *DLink
}

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。