/// <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); }
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); }
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); }