第十四 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; }
}