• C#简单实现LRU缓存


      最近跟同学吃饭扯淡的时候,由技术扯到薪资,又由薪资扯到他找工作时跟面试官是怎么扯淡拿高工资的,各种技术一顿侃,总之只要啥都了解就没问题了。谈到缓存的时候,我试探性的问了问- -你还记得LRU怎么写吗,他说啥完?我说没事。。

     写完这篇文章发给他- -鄙视完他让他请我再吃饭,标准的缓存LRU实现为哈希表+链表,这是热乎的双向链表,也是C#版本的。。C#实现双向链表 

    代码:

        public class LRUCache<T>
        {
            private int _size;//链表长度
            private int _capacity;//缓存容量 
            private Dictionary<int, ListNode<T>> _dic;//key +缓存数据
            private ListNode<T> _linkHead;
            public LRUCache(int capacity)
            {
                _linkHead = new ListNode<T>(-1, default(T));
                _linkHead.Next = _linkHead.Prev = _linkHead;
                this._size = 0;
                this._capacity = capacity;
                this._dic = new Dictionary<int, ListNode<T>>();
            }
    
            public T Get(int key)
            {
                if (_dic.ContainsKey(key))
                {
                    ListNode<T> n = _dic[key];
                    MoveToHead(n);
                    return n.Value;
                } 
                else
                {
                    return default(T);
                }
            }
            public void Set(int key, T value)
            {
                ListNode<T> n;
                if (_dic.ContainsKey(key))
                {
                    n = _dic[key];
                    n.Value = value;
                    MoveToHead(n);
                }
                else
                {
                    n = new ListNode<T>(key, value);
                    AttachToHead(n);
                    _size++;
                } 
                if (_size > _capacity)
                {
                    RemoveLast();// 如果更新节点后超出容量,删除最后一个
                    _size--;
                }
                _dic.Add(key, n);
            }
            // 移出链表最后一个节点
            private void RemoveLast()
            {
                ListNode<T> deNode = _linkHead.Prev;
                RemoveFromList(deNode);
                _dic.Remove(deNode.Key);
            }
            // 将一个孤立节点放到头部
            private void AttachToHead(ListNode<T> n)
            {
                n.Prev = _linkHead;
                n.Next = _linkHead.Next;
                _linkHead.Next.Prev = n;
                _linkHead.Next = n;
            }
            // 将一个链表中的节点放到头部
            private void MoveToHead(ListNode<T> n)
            {
                RemoveFromList(n);
                AttachToHead(n);
            }
            private void RemoveFromList(ListNode<T> n)
            {
                //将该节点从链表删除
                n.Prev.Next = n.Next;
                n.Next.Prev = n.Prev;
            }
        }
    
        public class ListNode<T>
        {
            public ListNode<T> Prev;
            public ListNode<T> Next;
            public T Value;
            public int Key;
    
            public ListNode(int key, T val)
            {
                Value = val;
                Key = key;
                this.Prev = null;
                this.Next = null;
            }
        }

    测试:

              LRUCache<int> cache = new LRUCache<int>(3);
                cache.Get(1);
                cache.Set(1, 1);
                cache.Set(2, 2);
                cache.Get(3);
                cache.Set(3, 3); 
                cache.Set(4, 4);
                cache.Get(2);
  • 相关阅读:
    php中&符号什么意思
    lucene 笔记
    yslow详细解释
    sqlserver中如何实现时间按月,日,小时分组查询
    用Lucene.net对数据库建立索引及搜索2
    lucene.net索引文件存储简析
    C #中的几个线程同步对象方法 1
    lucene 全文检索简介
    判断jquery对象是否可见
    Lucene.net多字段(Fields)、多索引目录(IndexSearcher)搜索
  • 原文地址:https://www.cnblogs.com/ylsforever/p/6511000.html
Copyright © 2020-2023  润新知