/// <summary>
        /// Add or update an entry to the LRUCache and put it in the front of the lru list.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="replace">whether to replace the value if already exist </param>
        /// <param name="charge">charge for capacity</param>
        /// <returns></returns>
        private bool Add(TKey key, ref TValue value, bool replace = true, ulong charge = 0)
        {
            bool evicted = false;
            bool itemLargerThanCapacity = false;

            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            using (_lock.GetWriterLock())
            {
                LinkedListNode <Entry <TKey, TValue> > node;
                // Check for existing item
                if (_map.TryGetValue(key, out node))
                {
                    _lruList.MoveToFront(node);
                    if (replace)
                    {
                        node.Value.Value = value;
                    }
                    else
                    {
                        value = node.Value.Value;
                    }
                    return(false);
                }

                if (_capacity == 0 || charge <= _capacity)
                {
                    // Add new item
                    var entry = new Entry <TKey, TValue> {
                        Key = key, Value = value, Charge = charge, CreationTime = DateTimeOffset.Now
                    };
                    _lruList.AddFirst(entry);
                    _map[key] = _lruList.First;
                    _usage   += charge;
                }
                else
                {
                    itemLargerThanCapacity = true;
                }

                // Verify size not exceeded
                while ((_maxEntries != 0 && _lruList.Count > _maxEntries) || (_capacity != 0 && _usage > _capacity))
                {
                    evicted = true;
                    RemoveOldest();
                }
            }

            if (itemLargerThanCapacity)
            {
                ItemOverCapacity?.Invoke(new KeyValuePair <TKey, TValue>(key, value));
            }
            return(evicted);
        }
Beispiel #2
0
        public DiskCache(string cacheRootPath, int maxEntryCount, IFileSystem fs = null)
        {
            _cacheRootPath = cacheRootPath;
            _cacheTmpPath  = Path.Combine(_cacheRootPath, "tmp");
            _fs            = fs;
            if (_fs == null)
            {
                _fs = new FileSystem();
            }

            _fs.DirectoryCreate(_cacheRootPath);
            _fs.DirectoryReCreate(_cacheTmpPath);

            _lruCache                   = new LRUCache <string, DiskCacheEntry>(maxEntryCount);
            _lruCache.ItemEvicted      += (KeyValuePair <string, DiskCacheEntry> pair) => FinishErase(pair.Key, pair.Value);
            _lruCache.ItemOverCapacity += (kv) => ItemOverCapacity?.Invoke(kv.Key);
        }
Beispiel #3
0
 public KeyPrefixCacheDecorator(string prefix, ICache cache)
 {
     _prefix    = prefix;
     _decorated = cache;
     _decorated.ItemOverCapacity += (key) => ItemOverCapacity?.Invoke(key);
 }
 private void TriggerItemCapacity(KeyValuePair <string, ArraySegment <byte> > kv)
 {
     ItemOverCapacity?.Invoke(kv.Key);
 }