第十四 LRU策略的内存缓存

LRU:是Least Recently Used的缩写,即最近最少使用,是一种常用的算法,选择最近最久未使用的页面予以淘汰。该算法赋予每个数据一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 t,当须淘汰一个页面时,选择现有数据中其 t 值最大的,即最近最少使用的页面予以淘汰。
 
我们在使用内存数据存储数据的时候,特别是大数据,因为我们不知道自己要存储的数据有多大,所有很有可能在存储的过程中造成内存溢出,
这个是有我们可以使用一个LRU策略来控制,下面是我写的一个基于LRU过期策略的一个内存哈希存储,使用链表做数据
 
------
 
-------
    /// <summary>
    /// 基于LRU过期策略的内存缓存,
    /// </summary>
    public class LRUHashMapCache
    {
        /// <summary>
        /// 设置缓存大小
        /// </summary>
        private int limit { get; set; }
        /// <summary>
        /// 哈希key存储
        /// </summary>
        private Dictionary<string, Node> hpCache;
        /// <summary>
        /// 头节点
        /// </summary>
        private Node Head { get; set; }
        /// <summary>
        /// 尾节点
        /// </summary>
        private Node End { get; set; }
        public LRUHashMapCache(int limit)
        {
            this.limit = limit;
            this.hpCache = new Dictionary<string, Node>();
        }
        /// <summary>
        /// 往缓存添加数据
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        public void PutNode(string key,object val)
        {
            if(!hpCache.ContainsKey(key))
            {
                Node node = new Node(key, val);
                if(hpCache.Keys.Count>=this.limit)
                {
                    RemoveNode(node);
                    hpCache.Remove(key);
                }
                AddNode(node);
                hpCache.Add(key, node);
            }
            else
            {
                Node node = hpCache[key];
                node.Values = val;
                RefreshNode(node);
            }
        }
 
        /// <summary>
        /// 获取缓存数据
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object GetNode(string key)
        {
            if (!hpCache.ContainsKey(key))
            {
                return null;
            }
            else
            {
                Node node = hpCache[key];
                return node.Values;
            }
        }
       
        /// <summary>
        /// 刷新节点
        /// </summary>
        /// <param name="node"></param>
        private void RefreshNode(Node node)
        {
            if(node==End)
            {
                return;
            }
            RemoveNode(node);
            AddNode(node);
 
        }
        /// <summary>
        /// 删除节点
        /// </summary>
        /// <param name="node"></param>
        private void RemoveNode(Node node)
        {
            if(Head==node && End==node)
            {
                node.Pre = null;
                node.Next = null;
            }
            else if (Head==node)
            {
                Head = Head.Next;
                Head.Pre = null;
            }
            else if(End==node)
            {
                End = End.Pre;
                End.Next = null;
            }
            else
            {
                node.Pre.Next = node.Next;
                node.Next.Pre = node.Pre;
            }
        }
 
        /// <summary>
        /// 链表添加节点
        /// </summary>
        /// <param name="node"></param>
        private void AddNode(Node node)
        {         
            if(End!=null)
            {
                End.Next = node;
                node.Pre = End;
                node.Next = null;
            }
            End = node;
            if (Head == null)
            {
                Head = node;
                node.Pre = null;
            }
        }
    }
 
    /// <summary>
    /// 节点链表结构
    /// </summary>
    public class Node
    {
        public Node(string key,object values)
        {
            this.Key = key;
            this.Values = values;
        }
        /// <summary>
        /// 数据的Key
        /// </summary>
        public string Key { get; set; }
 
        /// <summary>
        /// 数据值
        /// </summary>
        public object Values { get; set; }
 
        /// <summary>
        /// 上一个节点
        /// </summary>
        public Node Pre { get; set; }
        /// <summary>
        /// 下一个节点
        /// </summary>
        public Node Next { get; set; }
    }
posted @ 2019-10-16 11:15  瀚海行舟  阅读(174)  评论(0编辑  收藏  举报