/// <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);
     }
 }
Esempio n. 2
0
        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);
            }
        }
Esempio n. 3
0
        /// <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();
        }
    }
Esempio n. 5
0
            void Evict()
            {
                LruCacheItem item = RecencyList.First.Value;

                RecencyList.RemoveFirst();
                Nodes.Remove(item.Key);
            }
Esempio n. 6
0
        /// <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);
     }
 }
Esempio n. 8
0
        /// <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);
            }
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
            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);
            }
Esempio n. 11
0
        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);
                }
            }
        }
Esempio n. 12
0
        /// <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();
            }
        }
Esempio n. 13
0
        /// <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;
            }
        }
Esempio n. 14
0
            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;
            }