public FixedSizeCacheDict(int maxSize) { Max = maxSize; // List initialization if (maxSize != 0) { BackingListHead = new LRUCacheLinkedListNode <K, V>(); var previousNode = BackingListHead; var currentNode = BackingListHead; for (int i = 1; i < maxSize; i++) { currentNode = new LRUCacheLinkedListNode <K, V>(); previousNode.Next = currentNode; currentNode.Previous = previousNode; previousNode = currentNode; } BackingListTail = previousNode; } }
private void touch(LRUCacheLinkedListNode <K, V> node) { // Stitch the end if (node.Next == null) { BackingListTail = node.Previous; } // Stitch the middle else { node.Next.Previous = node.Previous; } if (node.Previous != null) { node.Previous.Next = node.Next; } // Put in front node.Previous = null; node.Next = BackingListHead; BackingListHead.Previous = node; BackingListHead = node; }
public void Register(K key, V item) { LRUCacheLinkedListNode <K, V> node; if (Max != 0) { // Eject last line of LRU Cache { var oldKey = BackingListTail.Key; if (oldKey != default) { FastAccessDict.Remove(oldKey); } if (BackingListTail.Value is IDisposable disposable) { disposable.Dispose(); } BackingListTail.Value = default; } // Add new line { var current = BackingListTail; current.Key = key; current.Value = item; touch(current); node = current; } } else { node = new LRUCacheLinkedListNode <K, V>(); node.Key = key; node.Value = item; } FastAccessDict.Add(key, node); }