|
@@ -1,81 +1,79 @@
|
|
|
type biNode struct {
|
|
|
- key int
|
|
|
- val int
|
|
|
+ key int
|
|
|
+ val int
|
|
|
prev *biNode
|
|
|
next *biNode
|
|
|
}
|
|
|
|
|
|
+type biList struct {
|
|
|
+ head *biNode
|
|
|
+ tail *biNode
|
|
|
+}
|
|
|
+
|
|
|
+func newBiList() *biList {
|
|
|
+ head, tail := &biNode{}, &biNode{}
|
|
|
+ head.next = tail
|
|
|
+ tail.prev = head
|
|
|
+ li := &biList{head, tail}
|
|
|
+ return li
|
|
|
+}
|
|
|
+
|
|
|
+func (li *biList) remove(node *biNode) {
|
|
|
+ node.prev.next = node.next
|
|
|
+ node.next.prev = node.prev
|
|
|
+}
|
|
|
+
|
|
|
+func (li *biList) insert(node *biNode) {
|
|
|
+ node.next = li.head.next
|
|
|
+ node.prev = li.head
|
|
|
+ li.head.next = node
|
|
|
+ node.next.prev = node
|
|
|
+}
|
|
|
+
|
|
|
type LRUCache struct {
|
|
|
capacity int
|
|
|
size int
|
|
|
cache map[int]*biNode
|
|
|
- head *biNode
|
|
|
- tail *biNode
|
|
|
+ list *biList
|
|
|
}
|
|
|
|
|
|
func Constructor(capacity int) LRUCache {
|
|
|
var lru LRUCache
|
|
|
lru.capacity = capacity
|
|
|
lru.cache = make(map[int]*biNode)
|
|
|
+ lru.list = newBiList()
|
|
|
return lru
|
|
|
}
|
|
|
|
|
|
func (this *LRUCache) Get(key int) int {
|
|
|
if node, ok := this.cache[key]; ok {
|
|
|
- this.moveToHead(node)
|
|
|
+ this.list.remove(node)
|
|
|
+ this.list.insert(node)
|
|
|
return node.val
|
|
|
}
|
|
|
return -1
|
|
|
}
|
|
|
|
|
|
-func (this *LRUCache) Put(key int, value int) {
|
|
|
+func (this *LRUCache) Put(key int, value int) {
|
|
|
+ if this.capacity == 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
if node, ok := this.cache[key]; ok {
|
|
|
+ this.list.remove(node)
|
|
|
+ this.list.insert(node)
|
|
|
node.val = value
|
|
|
- this.moveToHead(node)
|
|
|
return
|
|
|
- } // Already exsist, update value & move to head
|
|
|
- newHead := &biNode{key, value, nil, this.head}
|
|
|
- if this.size == 0 {
|
|
|
- this.head = newHead
|
|
|
- this.tail = newHead
|
|
|
- } else {
|
|
|
- this.head.prev = newHead
|
|
|
- this.head = newHead
|
|
|
}
|
|
|
- this.cache[key] = this.head
|
|
|
- this.size++ // Not exsist, add new head
|
|
|
- if this.size > this.capacity { // Remove tail
|
|
|
+ if this.size == this.capacity {
|
|
|
+ node := this.list.tail.prev
|
|
|
+ delete(this.cache, node.key)
|
|
|
+ this.list.remove(node)
|
|
|
this.size--
|
|
|
- delete(this.cache, this.tail.key)
|
|
|
- this.tail = this.tail.prev
|
|
|
- if this.tail == nil {
|
|
|
- this.head = nil
|
|
|
- } else {
|
|
|
- this.tail.next = nil
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func (this *LRUCache) moveToHead(node *biNode) {
|
|
|
- if node == this.head {
|
|
|
- return
|
|
|
- }
|
|
|
- if node == this.tail {
|
|
|
- this.tail.next = this.head
|
|
|
- this.head.prev = this.tail
|
|
|
- this.head = this.tail
|
|
|
- this.tail = this.tail.prev
|
|
|
- this.tail.next = nil
|
|
|
- this.head.prev = nil
|
|
|
- return
|
|
|
}
|
|
|
- prev, next := node.prev, node.next
|
|
|
- next.prev = prev
|
|
|
- prev.next = next
|
|
|
- node.prev = nil
|
|
|
- node.next = this.head
|
|
|
- this.head.prev = node
|
|
|
- this.head = node
|
|
|
+ newNode := &biNode{key, value, nil, nil}
|
|
|
+ this.list.insert(newNode)
|
|
|
+ this.cache[key] = newNode
|
|
|
+ this.size++
|
|
|
}
|
|
|
|
|
|
/**
|