public bool VisitAndTryRemove(T val, out T removeVal) { LRULInkedListNode <T> valNode = null; removeVal = default(T); bool isCacheContaionVal = cache.TryGetValue(val, out valNode); bool ret = false; if (isCacheContaionVal) { MoveNodeToTheFront(valNode); } else { LRULInkedListNode <T> node = PopNode(); node.val = val; cache.Add(val, node); LinkAtTheFront(node); if (capacity < cache.Count) { removeVal = tail.prev.val; cache.Remove(tail.prev.val); RemoveTheLastNode(); ret = true; } } return(ret); }
private void LinkAtTheFront(LRULInkedListNode <T> node) { LRULInkedListNode <T> headNext = head.Next; head.Next = node; node.prev = head; node.Next = headNext; headNext.prev = node; }
private void MoveNodeToTheFront(LRULInkedListNode <T> node) { LRULInkedListNode <T> prevNode = node.prev; LRULInkedListNode <T> nextNode = node.Next; prevNode.Next = nextNode; nextNode.prev = prevNode; LinkAtTheFront(node); }
private void GeneratePool() { int cap = this.pool.Capacity; for (int i = 0; i < cap; i++) { LRULInkedListNode <T> node = new LRULInkedListNode <T>(); pool.Add(node); } }
private void RemoveTheLastNode() { LRULInkedListNode <T> tailPrev = tail.prev; LRULInkedListNode <T> tailPrevPrev = tail.prev.prev; tailPrevPrev.Next = tail; tailPrev.prev = tailPrevPrev; RecycleNode(tailPrev); tailPrev = null; }
public LRUCache(int capacity) { this.capacity = capacity; this.cache = new Dictionary <T, LRULInkedListNode <T> >(this.capacity); this.pool = new List <LRULInkedListNode <T> >(this.capacity + POOL_EXTRA_SIZE); GeneratePool(); this.head = new LRULInkedListNode <T>(); this.tail = new LRULInkedListNode <T>(); Clear(); }
private LRULInkedListNode <T> PopNode() { LRULInkedListNode <T> node; if (pool.Count > 0) { int last = pool.Count - 1; node = pool[last]; pool.RemoveAt(last); } else { node = new LRULInkedListNode <T>(); } return(node); }
private void RecycleNode(LRULInkedListNode <T> node) { pool.Add(node); }