/// <summary> /// Sets the specific value for the specified key. /// </summary> /// <param name="key">The key for which value needs to be set.</param> /// <param name="value">The value to be set.</param> public void Set(TKey key, TValue value) { if (key == null) { throw new ArgumentNullException($"'{nameof(key)}' cannot be null."); } lock (_lock) { if (_dictionary.TryGetValue( key: key, value: out LRUChainItem <KeyValuePair <TKey, TValue> > lruChainItem)) // Key already present in cache. { // Promote the LRU chain item and update the value in the chain item. lruChainItem.ItemValue = new KeyValuePair <TKey, TValue>(key, value); _lruChain.Promote(lruChainItem); } else // Key does not exist in the cache. Add fresh. { // See if eviction is required. EvictIfRequired(); // Set the item in the cache. lruChainItem = new LRUChainItem <KeyValuePair <TKey, TValue> >(new KeyValuePair <TKey, TValue>(key, value)); _dictionary[key] = lruChainItem; _lruChain.AddFirst(lruChainItem); } } }
/// <summary> /// Adds item to the front of the list. /// </summary> public void AddFirst(LRUChainItem <TValue> item) { if (item == null) { throw new ArgumentNullException($"'{nameof(item)}' cannot be null"); } if (_head == null) // case of empty list { item.Previous = null; item.Next = null; _head = item; _tail = item; } else { // Create a link between the item and _head. item.Previous = null; item.Next = _head; _head.Previous = item; _head = item; // Tail doesn't update. } }
/// <summary> /// Removes the specified item. /// </summary> public void Remove(LRUChainItem <TValue> item) { if (item == null) { throw new ArgumentNullException($"'{nameof(item)}' cannot be null"); } // Update the link between the previous and next items. if (item.Previous != null) { item.Previous.Next = item.Next; } if (item.Next != null) { item.Next.Previous = item.Previous; } // Check if _tail needs to be updated. if (_tail == item) { _tail = item.Previous; } // Check if _head needs to be updated. if (_head == item) { _head = item.Next; } }
/// <summary> /// Promotes the item to the front of the list. /// </summary> public void Promote(LRUChainItem <TValue> item) { if (item == null) { throw new ArgumentNullException($"'{nameof(item)}' cannot be null"); } if (item == _head) { // Already at the front of the list. No action requried. return; } Remove(item); AddFirst(item); }