【问题标题】:Data Structure for Dictionary with Max Size [duplicate]具有最大大小的字典的数据结构
【发布时间】:2013-01-18 12:59:47
【问题描述】:

可能重复:
Is it there any LRU implementation of IDictionary?

我正在寻找一种类似于字典但只能包含一组键值对的数据结构。当一个键值对被添加到一个已经满的字典中时,一个最近没有被访问过的键值对将会被移除。

C# 中是否已经存在类似的东西?

我记得为操作系统类实现了类似的东西,并且数据结构用于决定应该将 RAM 的哪一部分分页到磁盘。这是通过将引用位与每个键值对相关联来完成的,该键值对在访问该对时设置为真。当需要删除一对时,键值对将被迭代,直到找到一个将其引用位设置为 false 的对。每对迭代的引用位将设置为 false,最后一个将被删除。

如果 C# 中不存在用于此的数据结构,那么我描述的算法是否是实现它的好方法?

【问题讨论】:

    标签: c# algorithm data-structures hash dictionary


    【解决方案1】:

    看起来 .Net 框架中还没有任何实现,所以这就是我最终使用的

    using System.Collections.Generic;
    using System.Linq;
    
    namespace MyProject.Util
    {
    public class LruCache<Key, Value>
    {
        public delegate Value ValueCreator();
    
        Dictionary<Key, ValueWithReference> cache;
    
        //The maximum number of elements that can fit in the cache.
        int maxCacheSize;
    
        IEnumerator<Value> valueRemover;
    
        public LruCache(int maxCacheSize) {
            this.cache = new Dictionary<Key, ValueWithReference>();
            this.maxCacheSize = maxCacheSize;
            this.valueRemover = GetKeyValuePairRemover().GetEnumerator();
        }
    
        /// <summary>
        /// Gets the value associated with the specified key. If it doesn't exist in the cache 
        /// then it will be created with createValue() and added to the cache. 
        /// </summary>
        public Value GetAndAddValue(Key key, ValueCreator createValue) {
            if (this.cache.ContainsKey(key) == false)
            {
                while (this.cache.Count >= this.maxCacheSize) {
                    this.valueRemover.MoveNext();
                }
    
                this.cache[key] = new ValueWithReference(createValue());
            }
    
            this.cache[key].recentlyUsed = true;
            return this.cache[key].value;
    
        }
    
        protected IEnumerable<Value> GetKeyValuePairRemover() { 
            while (true) {
                List<Key> keyList = this.cache.Keys.ToList();
    
                foreach(Key key in keyList) {
                    if (this.cache[key].recentlyUsed)
                    {
                        this.cache[key].recentlyUsed = false;
                    }
                    else {
                        Value removedValue = this.cache[key].value;
                        this.cache.Remove(key);
                        yield return removedValue;
                    }
                }
    
            }
        }
    
        protected class ValueWithReference
        {
            public Value value;
            public bool recentlyUsed;
    
            public ValueWithReference(Value value)
            {
                this.value = value;
                this.recentlyUsed = true;
            }
        }
    }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-11-26
      • 1970-01-01
      • 2011-11-07
      • 1970-01-01
      • 2014-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      相关资源
      最近更新 更多