1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
| package mylru
type DLinkerNode struct { key string value interface{} pre, post *DLinkerNode } type LRUCache struct { head, tail *DLinkerNode capacity, count int cache map[string]*DLinkerNode }
func newDLinkerNode(key string, value interface{}) *DLinkerNode { return &DLinkerNode{ key: key, value: value, } }
func NewLRUCache(capacity int) *LRUCache { lru := &LRUCache{ head: newDLinkerNode("", struct{}{}), tail: newDLinkerNode("", struct{}{}), capacity: capacity, cache: make(map[string]*DLinkerNode), } lru.head.post = lru.tail lru.tail.pre = lru.head return lru }
func (lru *LRUCache) Get(key string) (interface{}, bool) { node, ok := lru.cache[key] if !ok { return nil, ok } lru.moveToHead(node) return node.value, true }
func (lru *LRUCache) Put(key string, value interface{}) (interface{}, bool) { node, ok := lru.cache[key] if ok { node.value = value lru.moveToHead(node) return nil, false } node = newDLinkerNode(key, value) lru.addToHead(node) lru.cache[key] = node lru.count++ if lru.Size() > lru.capacity { removeNode := lru.removeTail() delete(lru.cache, removeNode.key) lru.count-- return removeNode.value, true } return nil, true }
func (lru *LRUCache) Del(key string) (interface{}, bool) { node, ok := lru.cache[key] if !ok { return nil, ok } lru.removeNode(node) delete(lru.cache, key) lru.count-- return node.value, true }
func (lru *LRUCache) moveToHead(node *DLinkerNode) { lru.removeNode(node) lru.addToHead(node) }
func (lru *LRUCache) removeNode(node *DLinkerNode) { node.pre.post = node.post node.post.pre = node.pre node.pre = nil node.post = nil }
func (lru *LRUCache) addToHead(node *DLinkerNode) { node.pre = lru.head node.post = lru.head.post lru.head.post.pre = node lru.head.post = node }
func (lru *LRUCache) removeTail() *DLinkerNode { node := lru.tail.pre lru.removeNode(node) return node }
|