基于LRU算法引擎的简单缓存机制

基于LRU算法引擎的简单缓存机制

一、缓存淘汰策略:

​ 当缓存容量不足时,将最近最少使用到的缓存直接淘汰掉。

二、实现数据结构

​ 双向链表+字典

三、实现大体思路

​ 先上核心代码吧

 `  /// <summary>
    /// 基于LRU算法的缓存机制
    /// 实现数据结构:双向链表+字典
    /// </summary>
    public class CacheLRUEngine<K,V> 
    {
        //双向链表,维护key是否被使用
        private DoublyLinkedList<K> _keyLruQue = new DoublyLinkedList<K>();
        //数据存储字典
        private Dictionary<K, V> _cacheMemory = new Dictionary<K, V>();
        //key和链表节点的字典
        private Dictionary<K, DoublyNode<K>> _keyToNodeMap = new Dictionary<K, DoublyNode<K>>();

        //缓存容量
        private Int32 _capacity = 100000;
        //缓存大小
        private Int32 _size = 0;
        public Int32 Capacity
        {
            get
            {
                return _capacity;
            }
            set
            {
                if (value <= 0)
                    throw new NonpositiveException("缓存容量必须大于零");
                _capacity = value;
            }
        }

        public Int32 Size
        {
            get {
                return _size;
            }
            
        }

        public bool Set(K key,V value)
        {
            try
            {
                if (_cacheMemory.ContainsKey(key))
                {
                    _cacheMemory.Add(key, value);
                }
                else
                {
                    if (_capacity - _size <= 0)
                    {
                        //删除最近最少使用的缓存
                        DelLRUCache();
                        _size--;
                    }
                    _cacheMemory.Add(key, value);
                    _keyToNodeMap.Add(key, _keyLruQue.Push(key));
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
            _size++;
            return true;
            
        }

        public V Get(K key)
        {
            if (_cacheMemory.ContainsKey(key))
            {
                //从key-node映射字典中获取到key对应的节点
                _keyToNodeMap.TryGetValue(key, out DoublyNode<K> node);

                //从LRU队列中删除key对应的节点
                node.PrePoint.NextPoint = node.NextPoint;
                node.NextPoint.PrePoint = node.PrePoint;
                node = null;

                //将key加入到LRU队列头部
                DoublyNode<K> addr = _keyLruQue.Push(key);

                //跟新映射
                _keyToNodeMap.Remove(key);
                _keyToNodeMap.Add(key, addr);


                //返回渠道的值
                bool res = _cacheMemory.TryGetValue(key, out V value);
                return res ? value : default(V);
            }
            else
            {
                throw new NonCacheException("key不存在");
            }
           
        }

        private bool DelLRUCache()
        {
            K tempKey = _keyLruQue.Tail.Value;
            _keyLruQue.DelFromTail();
            _keyToNodeMap.Remove(tempKey);
            _cacheMemory.Remove(tempKey);
            return true;
        }

        //删除缓存
        public bool DelCacheByKey(K key)
        {
            if (!_cacheMemory.ContainsKey(key))
                return true;
            _keyToNodeMap.TryGetValue(key,out DoublyNode<K> node);
            _keyLruQue.DelNode(node);
            _keyToNodeMap.Remove(key);
            _cacheMemory.Remove(key);
            return true;
        }

    }`

_keyLruQue双向链表为自实现双向链表数据结构,该双向链表主要负责维护LRU机制,链表头部是最近使用最多的数据,尾部是最近使用次数最少的数据。

_cacheMemory该字典用作数据存储器,是存储key-value被缓存数据的核心存储器。

_keyToNodeMap为key到对应链表节点的映射字典,可通过key找到_keyLruQue中对应的链表节点。

四、set方法的工作机制

当需要想cache中加入缓存时:

1.检查key是否已经存在,如果已经存在的话,则覆盖原来的值

2.如果不存在,则先去检查缓存容量是否足够,如果不足够,则删除_keyLruQue双向链表尾部的key对应的缓存,并将数据缓存入存储器。

3.容量足够则直接存入存储器。

五、get方法的工作机制

当需要从缓存中获取数据时:

1.根据key从_keyToNodeMap中获取到对应的链表节点,将该节点移动到_keyLruQue头部。

2.从_cacheMemory中获取到数据,直接返回即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
LRU(Least Recently Used)是一种常见的缓存淘汰算法,它的基本思想是:将最不常用的数据最先淘汰掉。 具体实现方式通常是将缓存空间划分为若干个桶(bucket),每个桶中存储一组数据,同时记录它们最后一次被访问的时间。当缓存空间满了,需要淘汰一些数据时,LRU算法会根据数据最近使用的频率和时间进行淘汰。 算法的核心思想是通过计数器(例如最近访问计数器)和哈希表(或排序列表)来实现。计数器用于记录每个数据项最后一次被访问的时间,哈希表或排序列表用于快速查找和删除数据项。 具体实现步骤如下: 1. 当缓存空间满了,需要淘汰一些数据时,遍历缓存中的所有数据项,并记录它们最后一次被访问的时间。 2. 根据时间戳和计数器的值,将数据项按照最近使用的频率进行排序。 3. 将排名最靠后的数据项从缓存中删除,并释放相应的空间。 4. 如果需要继续淘汰数据,重复步骤1-3,直到缓存空间不再满为止。 这种算法的优点是实现简单,易于理解和实现,并且具有较好的性能和效率。但是,它也有一些缺点,例如当缓存命中率较低时,需要频繁地进行淘汰和替换操作,导致缓存命中率进一步下降。此外,如果需要支持高并发访问,还需要考虑并发控制和线程安全等问题。 总之,LRU算法是一种常用的缓存淘汰算法,适用于需要快速响应和低延迟的应用场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浪舟子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值