Exemplo n.º 1
0
 private void MoveToHead(LRUCacheNode node)
 {
     _head.prev = node;
     node.next  = _head;
     node.prev  = null;
     _head      = node;
 }
Exemplo n.º 2
0
        public bool TryGetValue(K key, out V val)
        {
            _counters.CacheReadPerSec.Increment();
            LRUCacheNode node = null;

            lock (_syncRoot) {
                if (_data.TryGetValue(key, out node))
                {
                    _order.Remove(node.TimeKey);
                    node.TimeKey = Stopwatch.GetTimestamp();
                    AddOrder(node.TimeKey, key);
                }
            }
            if (node == null)
            {
                _counters.CacheHitRatio.IncreaseFraction(false);
                val = default(V);
                return(false);
            }
            else
            {
                _counters.CacheHitRatio.IncreaseFraction(true);
                val = node.Value;
                return(true);
            }
        }
Exemplo n.º 3
0
 private void Evict()
 {
     _keyToNodeDictionary.Remove(_tail.key);
     _tail = _tail?.prev;
     if (_tail?.next != null)
     {
         _tail.next = null;
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void Insert(string key, int value)
        {
            LRUCacheNode newEntry;

            if (_keyToNodeDictionary.ContainsKey(key))
            {
                _keyToNodeDictionary[key].val = value;
                newEntry = _keyToNodeDictionary[key];

                // Update MRU and LRU in case they point to this node
                if (newEntry == _tail)
                {
                    _tail = _tail.prev;
                }
                else if (newEntry == _head)
                {
                    _head = _head.next;
                }

                // Detach from DLL
                newEntry.Detach();
            }
            else
            {
                newEntry = new LRUCacheNode(key, value);

                // Eviction based on LRU
                if (_currentSize == _maxSize)
                {
                    Evict();
                }
                else
                {
                    _currentSize++; // Only increment if it is not contained and currentSize < maxsize
                }
                _keyToNodeDictionary.Add(newEntry.key, newEntry);
            }

            // Update MRU
            var prevHead = _head;

            _head      = newEntry;
            _head.next = prevHead;
            if (prevHead != null)
            {
                prevHead.prev = _head;
            }

            if (_tail == null)
            {
                _tail = newEntry;
            }
        }
Exemplo n.º 5
0
            public void Put(int key, int value)
            {
                if (_map.ContainsKey(key))
                {
                    var node = _map[key];
                    node.val = value;

                    if (_head == node)
                    {
                        return;
                    }
                    else if (node == _tail)
                    {
                        RemoveTail();
                    }
                    else
                    {
                        RemoveNode(node);
                    }

                    MoveToHead(node);
                }
                else
                {
                    var node = new LRUCacheNode(key, value);
                    _map.Add(key, node);
                    if (_count == _capacity) // evicts
                    {
                        MoveToHead(node);
                        _map.Remove(_tail.key);
                        RemoveTail();
                    }
                    else
                    {
                        if (_head == null) // count 0
                        {
                            _head = _tail = node;
                        }
                        else if (_head == _tail) // count 1
                        {
                            _tail.prev = node;
                            node.next  = _tail;
                            _head      = node;
                        }
                        else
                        {
                            MoveToHead(node);
                        }
                        _count++;
                    }
                }
            }
Exemplo n.º 6
0
 /// <summary>
 /// Helper function to detach a node from the DLL List
 /// </summary>
 public void Detach()
 {
     if (prev != null)
     {
         prev.next = next;
     }
     if (next != null)
     {
         next.prev = prev;
     }
     prev = null;
     next = null;
 }
Exemplo n.º 7
0
            private void RemoveNode(LRUCacheNode node)
            {
                var prev = node.prev;
                var next = node.next;

                if (prev != null)
                {
                    prev.next = next;
                }
                if (next != null)
                {
                    next.prev = prev;
                }
            }
Exemplo n.º 8
0
 private void RemoveTail()
 {
     _tail      = _tail.prev;
     _tail.next = null;
 }