package main
import "fmt"
type LRUCache struct {
length int
cap int
cache map[interface{}]*DoubleLinkNode
head *DoubleLinkNode
tail *DoubleLinkNode
}
// 双链表节点
// 头节点和尾节点不存数据,方便处理
type DoubleLinkNode struct {
pre *DoubleLinkNode
next *DoubleLinkNode
key interface{}
value interface{}
}
func (lru *LRUCache) Get(key interface{}) interface{} {
if _, ok := lru.cache[key]; !ok {
return -1
}
node := lru.cache[key]
lru.moveNodeToHead(node)
return node.value
}
func (lru *LRUCache) Put(key interface{}, value interface{}) {
if node, ok := lru.cache[key]; !ok {
newNode := &DoubleLinkNode{
key: key,
value: value,
}
if lru.length == lru.cap {
tailPre := lru.tail.pre
lru.removeNode(tailPre)
delete(lru.cache, tailPre.key)
lru.length--
}
lru.cache[key] = newNode
lru.headInsertNode(newNode)
lru.length++
} else {
node.value = value
lru.moveNodeToHead(node)
}
}
func (lru *LRUCache) moveNodeToHead(node *DoubleLinkNode) {
lru.removeNode(node)
lru.headInsertNode(node)
}
func (lru *LRUCache) removeNode(node *DoubleLinkNode) {
node.pre.next = node.next
node.next.pre = node.pre
}
func (lru *LRUCache) headInsertNode(node *DoubleLinkNode) {
node.next = lru.head.next
node.pre = lru.head
lru.head.next.pre = node
lru.head.next = node
}
func (lru *LRUCache) PrintLRUCache() {
node := lru.head.next
for node != lru.tail {
fmt.Printf("%s:%d ", node.key, node.value)
node = node.next
}
fmt.Println()
}
func NewLRUCache(cap int) *LRUCache {
if cap < 0 {
return nil
}
lru := &LRUCache{
cap: cap,
cache: make(map[interface{}]*DoubleLinkNode),
head: &DoubleLinkNode{},
tail: &DoubleLinkNode{},
}
lru.head.next = lru.tail
lru.tail.pre = lru.head
return lru
}
func main() {
lru := NewLRUCache(1)
lru.Put("a", 1)
lru.PrintLRUCache()
lru.Put("b", 2)
lru.PrintLRUCache()
lru = NewLRUCache(3)
lru.Put("a", 1)
lru.Put("b", 2)
lru.Put("c", 3)
lru.PrintLRUCache()
lru.Put("d", 4)
lru.PrintLRUCache()
lru.Get("b")
lru.PrintLRUCache()
}