Пример #1
0
        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();
                }
            }
        }
Пример #2
0
        public LRUCache(int capacity)
        {
            if (capacity <= 0)
            {
                throw new ArgumentOutOfRangeException($"invalid argument {nameof(capacity)}");
            }

            this.capacity    = capacity;
            linkedDictionary = new LinkedDictionary <TKey, TValue>(capacity);
        }
Пример #3
0
        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]);
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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;
        }
Пример #6
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);
            }
        }
Пример #7
0
 public FIFOCache(int capacity)
 {
     this.capacity         = capacity;
     this.linkedDictionary = new LinkedDictionary <TKey, TValue>();
 }