/// <summary> /// Looks for a value for the matching <paramref name="key"/>. If not found, /// calls <paramref name="valueGenerator"/> to retrieve the value and add it to /// the cache. /// </summary> /// <param name="key"> /// The key of the value to look up. /// </param> /// <param name="valueGenerator"> /// Generates a value if one isn't found. /// </param> /// <returns> /// The requested value. /// </returns> public TValue Get(TKey key, Func <TValue> valueGenerator) { lock (this.cacheMap) { LinkedListNode <LruCacheItem> node; TValue value; if (this.cacheMap.TryGetValue(key, out node)) { value = node.Value.Value; this.lruList.Remove(node); this.lruList.AddLast(node); } else { value = valueGenerator(); if (this.cacheMap.Count >= this.Capacity) { this.RemoveFirst(); } LruCacheItem cacheItem = new LruCacheItem(key, value); node = new LinkedListNode <LruCacheItem>(cacheItem); this.lruList.AddLast(node); this.cacheMap.Add(key, node); } return(value); } }
public void Set(TKey key, TValue val) { if (val == null) { Delete(key); } if (_cacheMap.TryGetValue(key, out LinkedListNode <LruCacheItem> node)) { node.Value.Value = val; _lruList.Remove(node); _lruList.AddLast(node); } else { if (_cacheMap.Count >= _capacity) { RemoveFirst(); } LruCacheItem cacheItem = new LruCacheItem(key, val); LinkedListNode <LruCacheItem> newNode = new LinkedListNode <LruCacheItem>(cacheItem); _lruList.AddLast(newNode); _cacheMap.Add(key, newNode); } }
/// <summary> /// Looks for a value for the matching <paramref name="key"/>. If not found, /// calls <paramref name="valueGenerator"/> to retrieve the value and add it to /// the cache. /// </summary> /// <param name="key"> /// The key of the value to look up. /// </param> /// <param name="valueGenerator"> /// Generates a value if one isn't found. /// </param> /// <returns> /// The requested value. /// </returns> public TValue Get(TKey key, Func <TKey, TValue> valueGenerator) { lock (_map) { LinkedListNode <LruCacheItem> node; TValue value; if (_map.TryGetValue(key, out node)) { value = node.Value.Value; _list.Remove(node); _list.AddLast(node); } else { value = valueGenerator(key); if (_map.Count >= Capacity) { RemoveFirst(); } var cacheItem = new LruCacheItem(key, value); node = new LinkedListNode <LruCacheItem>(cacheItem); _list.AddLast(node); _map.Add(key, node); } return(value); } }
public async Task <TValue> GetAsync(TKey key, Func <Task <TValue> > valueGenerator, CancellationToken cancellationToken = default) { try { await this.locker.WaitAsync(cancellationToken); TValue value; if (this.cacheMap.TryGetValue(key, out var node)) { value = node.Value.Value; this.lruList.Remove(node); this.lruList.AddLast(node); } else { value = await valueGenerator(); if (this.cacheMap.Count >= this.Capacity) { this.RemoveFirst(); } LruCacheItem cacheItem = new LruCacheItem(key, value); node = new LinkedListNode <LruCacheItem>(cacheItem); this.lruList.AddLast(node); this.cacheMap.Add(key, node); } return(value); } finally { this.locker.Release(); } }
void Evict() { LruCacheItem item = RecencyList.First.Value; RecencyList.RemoveFirst(); Nodes.Remove(item.Key); }
/// <summary> /// Looks for a value for the matching <paramref name="key"/>. If not found, /// calls <paramref name="valueGenerator"/> to retrieve the value and add it to /// the cache. /// </summary> /// <param name="key"> /// The key of the value to look up. /// </param> /// <param name="valueGenerator"> /// Generates a value if one isn't found. /// </param> /// <returns> /// The requested value. /// </returns> public TValue Get(TKey key, Func <TValue> valueGenerator) { _lock.EnterUpgradeableReadLock(); try { TValue value; if (this._cacheMap.TryGetValue(key, out var node)) { value = node.Value.Value; _lock.EnterWriteLock(); try { this._lruList.Remove(node); this._lruList.AddLast(node); } finally { _lock.ExitWriteLock(); } } else { value = valueGenerator(); var cacheItem = new LruCacheItem(key, value); node = new LinkedListNode <LruCacheItem>(cacheItem); _lock.EnterWriteLock(); try { if (this._cacheMap.Count >= this.Capacity) { this.RemoveFirst(); } this._lruList.AddLast(node); this._cacheMap[key] = node; } finally { _lock.ExitWriteLock(); } } return(value); } finally { _lock.ExitUpgradeableReadLock(); } }
/// <summary> /// Adds the specified key and value to the dictionary. /// </summary> /// <param name="key"> /// The key of the element to add. /// </param> /// <param name="value"> /// The value of the element to add. The value can be null for reference types. /// </param> public void Add(TKey key, TValue value) { lock (this.cacheMap) { if (this.cacheMap.Count >= this.Capacity) { this.RemoveFirst(); } LruCacheItem cacheItem = new LruCacheItem(key, value); LinkedListNode <LruCacheItem> node = new LinkedListNode <LruCacheItem>(cacheItem); this.lruList.AddLast(node); this.cacheMap.Add(key, node); } }
/// <summary> /// Adds the specified key and value to the dictionary. /// </summary> /// <param name="key"> /// The key of the element to add. /// </param> /// <param name="value"> /// The value of the element to add. The value can be null for reference types. /// </param> public void Add(TKey key, TValue value) { lock (_map) { if (_map.Count >= Capacity) { RemoveFirst(); } var cacheItem = new LruCacheItem(key, value); var node = new LinkedListNode <LruCacheItem>(cacheItem); _list.AddLast(node); _map.Add(key, node); } }
public bool Add(TKey key, TValue value) { var flag = false; if (items.Count >= size) { RemoveFirst(); flag = true; } var cacheItem = new LruCacheItem(key, value); var node = new LinkedListNode <LruCacheItem>(cacheItem); evictList.AddLast(node); items[key] = node; return(flag); }
public bool TryGetValue(K key, out V value) { LinkedListNode <LruCacheItem> node; if (!Nodes.TryGetValue(key, out node)) { value = default(V); return(false); } LruCacheItem item = node.Value; RecencyList.Remove(node); RecencyList.AddLast(node); value = item.Value; return(true); }
public void Add(TKey key, TValue value) { lock (m_cacheMap) { if (!m_cacheMap.ContainsKey(key)) { if (m_cacheMap.Count >= Capacity) { RemoveFirst(); } var cacheItem = new LruCacheItem(key, value); var node = new LinkedListNode <LruCacheItem>(cacheItem); m_lruList.AddLast(node); m_cacheMap.Add(key, node); } } }
/// <summary> /// Adds the specified key and value to the dictionary. /// </summary> /// <param name="key"> /// The key of the element to add. /// </param> /// <param name="value"> /// The value of the element to add. The value can be null for reference types. /// </param> public void Add(TKey key, TValue value) { var cacheItem = new LruCacheItem(key, value); var node = new LinkedListNode <LruCacheItem>(cacheItem); _lock.EnterWriteLock(); try { if (this._cacheMap.Count >= this.Capacity) { this.RemoveFirst(); } this._lruList.AddLast(node); this._cacheMap[key] = node; } finally { _lock.ExitWriteLock(); } }
/// <summary> /// Adds the specified key and value to the dictionary. /// </summary> /// <param name="key"> /// The key of the element to add. /// </param> /// <param name="value"> /// The value of the element to add. The value can be null for reference types. /// </param> public void Add(TKey key, TValue value) { lock (this.cacheMap) { if (this.cacheMap.Count >= this.Capacity) { this.RemoveFirst(); } LruCacheItem cacheItem = new LruCacheItem(key, value); LinkedListNode <LruCacheItem> node = new LinkedListNode <LruCacheItem>(cacheItem); // https://stackoverflow.com/questions/754233/is-it-there-any-lru-implementation-of-idictionary/3719378#comment89086529_3719378 if (this.cacheMap.TryGetValue(key, out var oldNode)) { this.lruList.Remove(oldNode); } this.lruList.AddLast(node); this.cacheMap[key] = node; } }
public void Set(K key, V value) { LinkedListNode <LruCacheItem> node; if (Nodes.TryGetValue(key, out node)) { RecencyList.Remove(node); node.Value.Value = value; } else { if (Nodes.Count >= Capacity) { Evict(); } var item = new LruCacheItem(key, value); node = new LinkedListNode <LruCacheItem>(item); } RecencyList.AddLast(node); Nodes[key] = node; }