zoukankan      html  css  js  c++  java
  • C# Collection for "most recently used"

    C# Collection for "most recently used"

    I would suggest a LinkedList collection. The LinkedList holds references to the first and last node in the list (effectively letting you travel in LRU/MRU order). It also has AddFirst and Remove methods so you can remove the value and move it when a value from the list is used. MSDN

    Efficient modelling of an MruList in C# or Java

    回答1

    Here's a Cache class that stores objects by the time they were accessed. More recent items bubble to the end of the list. The cache operates off an indexer property that takes an object key. You could easily replace the internal dictionary to a list and reference the list from the indexer.

    BTW, you should rename the class to MRU as well :)

    class Cache
        {
            Dictionary<object, object> cache = new Dictionary<object, object>();
    
            /// <summary>
            /// Keeps up with the most recently read items.
            /// Items at the end of the list were read last. 
            /// Items at the front of the list have been the most idle.
            /// Items at the front are removed if the cache capacity is reached.
            /// </summary>
            List<object> priority = new List<object>();
            public Type Type { get; set; }
            public Cache(Type type)
            {
                this.Type = type;
    
                //TODO: register this cache with the manager 
    
            }
            public object this[object key]
            { 
                get 
                {
                    lock (this)
                    {
                        if (!cache.ContainsKey(key)) return null;
                        //move the item to the end of the list                    
                        priority.Remove(key);
                        priority.Add(key);
                        return cache[key];
                    }
                }
                set 
                {
                    lock (this)
                    {
                        if (Capacity > 0 && cache.Count == Capacity)
                        {
                            cache.Remove(priority[0]);
                            priority.RemoveAt(0);
                        }
                        cache[key] = value;
                        priority.Remove(key);
                        priority.Add(key);
    
                        if (priority.Count != cache.Count)
                            throw new Exception("Capacity mismatch.");
                    }
                }
            }
            public int Count { get { return cache.Count; } }
            public int Capacity { get; set; }
    
            public void Clear()
            {
                lock (this)
                {
                    priority.Clear();
                    cache.Clear();
                }
            }
        }
    

    回答2

    Couple of comments about your approach

    • Why have Store return T? I know what I just added, returning it back to me is un-necessary unless you explicitly want method chaining
    • Refactor GetNext() into a new class. It represents a different set of functionality (storage vs. cursor traversal) and should be represented by a separate interface. It also has usability concerns as what happens when two different methods active on the same stack want to traverse the structure?
    • GetList() should likely return IEnumerable<T>. Returning List<T> either forces an explicit copy up front or returns a pointer to an underlying implementation. Neither is a great choice.

    As for what is the best structure to back the interface. It seems like the best to implement is to have a data structure which is efficient at adding to one end, and removing from the other. A doubly linked list would suit this nicely.

    回答3

    You can build this up with a Collections.Generic.LinkedList<T>. When you push an item into a full list, delete the last one and insert the new one at the front. Most operations should be in O(1) which is better than a array-based implementation.

  • 相关阅读:
    斐波那契数列
    进制转换为伪代码
    python模拟进程
    第十一周学习总结
    第十周学习总结
    第九周学习总结
    俄罗斯方块
    熟悉编程语言
    小学四则运算
    第八周学习总结
  • 原文地址:https://www.cnblogs.com/chucklu/p/15324906.html
Copyright © 2011-2022 走看看