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.

  • 相关阅读:
    解决拼团首页swiper组件手动轮播卡顿问题
    mac上charels抓包工具使用技巧
    加载图片优化(先用一张小图片做高斯模糊, 再加载大图)
    requirejs2读书笔记
    escape encodeURI encodeURIComponent区别
    js与cookie的domain和path之间的关系
    Oracle使用——数据泵导入导出数据库——impdp/expdp使用
    Oracle基础知识点——Oracle服务端和客户端
    Oracle使用——oracle11g安装——Oracle要求的结果: 5.0,5.1,5.2,6.0 6.1 之一 实际结果: 6.2
    Spring 学习——Spring AOP——AOP配置篇Advice(有参数传递)
  • 原文地址:https://www.cnblogs.com/chucklu/p/15324906.html
Copyright © 2011-2022 走看看