コード例 #1
0
ファイル: SlickCache.cs プロジェクト: MikeDub/ICacheChallenge
        /// <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);
                }
            }
        }