private void Shrink() { int removed = 0; int toRemove = dictionary.Count - (int)(shrinkFactor * capacity); while (removed < toRemove) { LinkedDictionary <TKey, ValueWrapper> dict = GetDictByFrequency(lowestFrequency); if (dict.Count == 0) { throw new Exception(); } while (dict.Count > 0 && removed < toRemove) { var key = dict.FirstKey; bool r = dict.Remove(key); dictionary.Remove(key); ++removed; } if (dict.Count == 0) { UpdateLowestFrequency(); } } }
public LRUCache(int capacity) { if (capacity <= 0) { throw new ArgumentOutOfRangeException($"invalid argument {nameof(capacity)}"); } this.capacity = capacity; linkedDictionary = new LinkedDictionary <TKey, TValue>(capacity); }
private LinkedDictionary <TKey, ValueWrapper> GetDictByFrequency(int frequency) { if (frequency < 0 || frequency > maxFrequency) { throw new Exception(); } if (dictByFrequency[frequency] == null) { dictByFrequency[frequency] = new LinkedDictionary <TKey, ValueWrapper>(); } return(dictByFrequency[frequency]); }
public bool Remove(TKey key) { ValueWrapper wrapper = default; if (dictionary.TryGetValue(key, out wrapper)) { LinkedDictionary <TKey, ValueWrapper> dict = GetDictByFrequency(wrapper.frequency); dict.Remove(key); if (lowestFrequency == wrapper.frequency) { UpdateLowestFrequency(); } return(true); } else { return(false); } }
public void Add(TKey key, TValue value) { if (dictionary.ContainsKey(key)) { throw new ArgumentException("An item with the same key has already been added"); } if (dictionary.Count == capacity) { Shrink(); } LinkedDictionary <TKey, ValueWrapper> dict = GetDictByFrequency(0); ValueWrapper wrapper = new ValueWrapper(value, 0); dict.Add(key, wrapper); dictionary[key] = wrapper; lowestFrequency = 0; }
public bool TryGetValue(TKey key, out TValue value) { ValueWrapper wrapper = default; if (dictionary.TryGetValue(key, out wrapper)) { int currentFrequency = wrapper.frequency; if (currentFrequency < maxFrequency) { int nextFrequency = currentFrequency + 1; LinkedDictionary <TKey, ValueWrapper> curDict = GetDictByFrequency(currentFrequency); LinkedDictionary <TKey, ValueWrapper> nextDict = GetDictByFrequency(nextFrequency); curDict.Remove(key); nextDict.Add(key, wrapper); wrapper.frequency = nextFrequency; dictionary[key] = wrapper; if (lowestFrequency == currentFrequency && curDict.Count == 0) { lowestFrequency = nextFrequency; } } else { // f相同时 用LRU策略 LinkedDictionary <TKey, ValueWrapper> dict = GetDictByFrequency(currentFrequency); dict.Remove(key); dict.Add(key, wrapper); } value = wrapper.value; return(true); } else { value = default; return(false); } }
public FIFOCache(int capacity) { this.capacity = capacity; this.linkedDictionary = new LinkedDictionary <TKey, TValue>(); }