// If the size is exceeded we remove the root element as it is the least used element private void RemoveIfNecessary() { if (GetSize() == maxSize) { var tmp = Root.Next; tmp.Previous = null; Root = tmp; } }
// Add an item in the cache private LeastRecentlyUsedCacheItem <T> Add(T itemToAdd) { // Create the root node if (Root is null) { Root = new LeastRecentlyUsedCacheItem <T> { Item = itemToAdd, Next = null, Previous = null, UsedAt = DateTime.UtcNow }; return(Root); } else { // Remove an item if the list is full RemoveIfNecessary(); var tmp = Root; while (tmp.Next != null) { tmp = tmp.Next; } // We had the new node at the end as it is the most recently used element tmp.Next = new LeastRecentlyUsedCacheItem <T> { Item = itemToAdd, Next = null, Previous = tmp, UsedAt = DateTime.UtcNow }; return(tmp); } }
// Sort the list from the least used to the most recently used private void SortList(LeastRecentlyUsedCacheItem <T> root) { if (root is null || root.Next is null) { return; } // If the current node has been used more recently than the next one we swap them if (root.UsedAt > root.Next.UsedAt) { var tmp = root.Next; var previous = root.Previous; root.Next = tmp.Next; root.Previous = tmp; tmp.Previous = previous; tmp.Next = previous?.Next ?? root; // If we swap the first item in the list there is no previous element to it if (previous != null) { previous.Next = tmp; } else { Root = tmp; // We set the new root of the list } // Sort the list with the current node SortList(root); } else { // Sort from the next node SortList(root.Next); } }