// remove target node from current frequency double-linked list,
        // and then promote it to higher frequency double-linked list
        private void PromoteNode(LFUNode node)
        {
            LFUDoubleLinkedList dll = frequencyMap[node.Frequency];

            dll.RemoveNode(node);
            if (dll.Count == 0)
            {
                frequencyMap.Remove(node.Frequency);
                if (minFrequency == node.Frequency)
                {
                    minFrequency++;
                }
            }
            node.Frequency++;
            if (!frequencyMap.ContainsKey(node.Frequency))
            {
                frequencyMap[node.Frequency] = new LFUDoubleLinkedList();
            }
            frequencyMap[node.Frequency].AddToTop(node);
        }
        public void Add(int key, int value)
        {
            if (capacity == 0)
            {
                return;
            }

            // update the value of that node and then promote the node
            if (map.ContainsKey(key))
            {
                LFUNode node = map[key];
                node.Value = value;
                PromoteNode(node);
            }
            else
            {
                // remove the LFU node
                if (count == capacity)
                {
                    LFUDoubleLinkedList dll     = frequencyMap[minFrequency];
                    LFUNode             lfuNode = dll.RemoveLFUNode();
                    if (dll.Count == 0)
                    {
                        frequencyMap.Remove(minFrequency);
                    }
                    map.Remove(lfuNode.Key);
                    count--;
                }

                // add a new node
                LFUNode node = new LFUNode(key, value);
                minFrequency = node.Frequency;
                map[key]     = node;
                if (!frequencyMap.ContainsKey(node.Frequency))
                {
                    frequencyMap[node.Frequency] = new LFUDoubleLinkedList();
                }
                frequencyMap[node.Frequency].AddToTop(node);
                count++;
            }
        }