/// <inheritdoc /> public void AddOrUpdate(TKey key, TValue value) { SpinLock sLock = new SpinLock(); bool lockTaken = false; try { sLock.Enter(ref lockTaken); //Support updating the cache (find by key and update the value) _cache.TryGetValue(key, out var valueToUpdate); if (valueToUpdate != null) { valueToUpdate.Value = value; _mostRecentlyUsed = valueToUpdate; //Eviction policy shouldn't be required when just performing an update. return; } // Insert the new node at the right-most end of the linked-list (recently used) Node <TKey, TValue> myNode = new Node <TKey, TValue>(_mostRecentlyUsed, null, key, value); //Support Adding to the cache _mostRecentlyUsed.Next = myNode; _cache.Add(key, myNode); _mostRecentlyUsed = myNode; //When an item is added to the cache, a check should be run to see if the cache size exceeds the maximum number of elements permitted. // Delete the left-most entry and update the least recently used pointer if (_evictionPolicy.MemberRequiresEviction()) { //If this is the case, then the least recently added/updated/retrieved item should be evicted from the cache. _cache.Remove(_leastRecentlyUsed.Key); _leastRecentlyUsed = _leastRecentlyUsed.Next; _leastRecentlyUsed.Previous = null; } //Update cache size else { // If this is the only node in the list, also set it as the least recently used. if (_evictionPolicy.CacheSize == 0) { _leastRecentlyUsed = myNode; } _evictionPolicy.CacheSize++; } } finally { if (lockTaken) { sLock.Exit(false); } } }