LRU最近最少使用缓存集合
编码中涉及到资源管理就会经常使用到最近最少使用淘汰原理(LRU),比如说最近打开的文章列表管理、或者游戏中动态加载地图、音乐一样。使用LRU可以提高效率。本文实现了一个完整功能的LRU集合,可用于各种诸如此类需要缓存机制的地方。
/// <summary>/// 使用最近最少算法进行淘汰的缓存集合,用于缓存数据./// 提供了多线程安全访问功能/// </summary>/// <remarks> /// 1、调用方在每使用一个数据之后,调用UpdateRecentlyUsed函数将该数据/// 置为最近访问。函数会将该条目的读取权值设为最大值。/// 2、在使用Add或者Insert添加条目时,如果缓存数目已达到设定的CacheSize值,/// 则会根据删除掉缓存列表中读取权值最小的条目。再进行添加/// </remarks>public class LRUCacheList<T> : IList<T>{#region Property/// <summary>/// 实际存放缓存条目的列表/// </summary>private List<T> m_listData;/// <summary>/// 存放与m_listData依次对应条目的最近读取记录/// </summary>private List<uint> m_listReadWeight;/// <summary>/// 当前最大的读取记录权值,用来计算下一个读取值/// </summary>private uint m_iMaxWeight;/// <summary>/// 一个无符号整数的最大值/// </summary>private const uint c_MaxWeight = 0xffffffff;private Object m_lockObj = new object();/// <summary>/// 读取和设置缓存大小,指定最多缓存的对象数目/// </summary>public int CacheSize { get; set; }#endregion#region Method/// <summary>/// /// </summary>/// <param name="cacheSize">缓存数目</param>public LRUCacheList(int cacheSize){m_listData = new List<T>(cacheSize);m_listReadWeight = new List<uint>(cacheSize);CacheSize = cacheSize;}/// <summary>/// 移除掉最近最少使用的条目/// </summary>protected void RemoveLeastRecentlyUsed(){lock (m_lockObj){uint min = c_MaxWeight;int minIndex = -1;for (int i = 0; i < m_listReadWeight.Count; i++){if (m_listReadWeight[i] < min){min = m_listReadWeight[i];minIndex = i;}}if (minIndex != -1){m_listReadWeight.RemoveAt(minIndex);m_listData.RemoveAt(minIndex);}}}/// <summary>/// 更新指定位置的权重值为最近访问/// </summary>/// <param name="index"></param>public void UpdateRecentlyUsed(T item){lock (m_lockObj){int index = m_listData.IndexOf(item);if (index != -1)UpdateRecentlyUsed(index);}}/// <summary>/// 更新指定位置的权重值为最近访问/// </summary>/// <param name="index"></param>public void UpdateRecentlyUsed(int index){m_listReadWeight[index] = NextMaxWeight();}/// <summary>/// 清除掉所有缓存的内容/// </summary>public void Clear(){lock (m_lockObj){if (m_listData != null)m_listData.Clear();if (m_listReadWeight != null)m_listReadWeight.Clear();m_iMaxWeight = 0;}}/// <summary>/// 获取并设置下一个最大的权重值/// </summary>/// <returns></returns>public uint NextMaxWeight(){lock (m_lockObj){//到达最大值重置if (m_iMaxWeight == c_MaxWeight - 1){m_iMaxWeight = 0;for (int i = 0; i < m_listReadWeight.Count; i++){m_listReadWeight[i] = 0;}}m_iMaxWeight++;return m_iMaxWeight;}}/// <summary>/// 添加一个条目并设置为最近访问/// </summary>/// <param name="item"></param>public void AddRecently(T item){lock (m_lockObj){while (CacheSize > 0 && m_listData.Count >= CacheSize)RemoveLeastRecentlyUsed();m_listData.Add(item);m_listReadWeight.Add(NextMaxWeight());}}/// <summary>/// 插入一个条目并设置为最近访问/// </summary>/// <param name="index"></param>/// <param name="item"></param>public void InsertRecently(int index, T item){lock (m_lockObj){while (CacheSize > 0 && m_listData.Count >= CacheSize)RemoveLeastRecentlyUsed();m_listData.Insert(index, item);m_listReadWeight.Insert(index, NextMaxWeight());}}#endregion#region 实现IList<T> 接口public void Add(T item){lock (m_lockObj){while (CacheSize > 0 && m_listData.Count >= CacheSize)RemoveLeastRecentlyUsed();m_listData.Add(item);m_listReadWeight.Add(0);}}/// <summary>/// /// </summary>/// <param name="item"></param>/// <returns></returns>public int IndexOf(T item){return m_listData.IndexOf(item);}public void Insert(int index, T item){lock (m_lockObj){while (CacheSize > 0 && m_listData.Count >= CacheSize)RemoveLeastRecentlyUsed();m_listData.Insert(index, item);m_listReadWeight.Insert(index, 0);}}public void RemoveAt(int index){lock (m_lockObj){m_listData.RemoveAt(index);m_listReadWeight.RemoveAt(index);}}public T this[int index]{get{return m_listData[index];}set{m_listData[index] = value;}}public bool Contains(T item){return m_listData.Contains(item);}public void CopyTo(T[] array, int arrayIndex){m_listData.CopyTo(array, arrayIndex);}public int Count{get { return m_listData.Count; }}public bool IsReadOnly{get { return false; }}public bool Remove(T item){lock (m_lockObj){int index = m_listData.IndexOf(item);if (index != -1)m_listReadWeight.RemoveAt(index);return m_listData.Remove(item);}}public IEnumerator<T> GetEnumerator(){return m_listData.GetEnumerator();}System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator(){return m_listData.GetEnumerator();}#endregion}
转载于:https://www.cnblogs.com/Kecp/archive/2012/12/02/2798579.html
LRU最近最少使用缓存集合相关推荐
- LeetCode LRU Cache(最近最少使用缓存)
问题:设计一个最近最少使用缓存.支持get和put操作 1.如果get(key)中,key在缓存中不存在,返回-1 2.put(key,value),如果key在缓存中不存在,则插入.当缓存到达容量时 ...
- ❤️缓存集合(一级缓存、二级缓存、缓存原理以及自定义缓存—源码+图文分析,建议收藏) ❤️
❤️缓存集合(一级缓存.二级缓存.缓存原理以及自定义缓存-源码+图文分析,建议收藏) ❤️ 查询 : 连接数据库 ,耗资源!一次查询的结果,给他暂存在一个可以直接取到的地方!--> 内存 : 缓 ...
- 数据结构LRUCache(Least Recently Used – 最近最少使用缓存)
题目要求: 设计一个数据结构,实现LRU Cache的功能(Least Recently Used – 最近最少使用缓存).它支持如下2个操作: get 和 put. int get(in ...
- 【EventBus】事件通信框架 ( 订阅类-订阅方法缓存集合 | 事件类型-订阅者集合 | 订阅对象-事件类型集合 )
文章目录 前言 一.订阅类-订阅方法缓存集合 二.事件类型-订阅者集合 三.订阅对象-事件类型集合 前言 首先声明几个数据结构 , 参考 [EventBus]EventBus 源码解析 ( 注册订阅者 ...
- 高性能Javascript 用局部变量缓存集合元素
document.images; 由于集合元素是处于实时状态的实时存在,它与底层dom连接着.在遍历它的每一个属性或length时都会带来查找,从而性能开销很高. 这里是有关集合元素在循环处理时的优化 ...
- 将redis当做使用LRU算法的缓存来使用
当Redis被当做缓存来使用,当你新增数据时,让它自动地回收旧数据是件很方便的事情.这个行为在开发者社区非常有名,因为它是流行的memcached系统的默认行为. LRU是Redis唯一支持的回收方法 ...
- java实现LRU、FIFO缓存
1.LRU缓存 1)LRU缓存的思想: 固定缓存大小,需要给缓存分配一个固定的大小. 每次读取缓存都会改变缓存的使用时间,将缓存的存在时间重新刷新. 需要在缓存满了后,将最近最久未使用的缓存删除,再添 ...
- 实现 LRU 缓存算法
1 LRU 缓存介绍 LRU 算法全称是最近最少使用算法(Least Recently Use),是一种简单的缓存策略.顾名思义,LRU 算法会选出最近最少使用的数据进行淘汰. 那么什么是缓存呢?缓存 ...
- LeetCode实战:LRU缓存机制
背景 为什么你要加入一个技术团队? 如何加入 LSGO 软件技术团队? 我是如何组织"算法刻意练习活动"的? 为什么要求团队的学生们写技术Blog 题目英文 Design and ...
最新文章
- ‘numpy.float64‘ object is not callable
- TreaponseHeader
- java struts2标签库 常用标签
- 【PAT】B1058 选择题(20 分)
- 分布式锁中的王者方案:Redisson
- Servlet执行时要实现的方法
- log4j 控制台和文件输出乱码问题解决
- python copy函数用法_python shutil模块函数copyfile和copy的区别
- MemCache对PHP页面的缓存加速优化
- iOS中的坑:URL不识别##
- 绘制等腰梯形c语言,如何用几何画板快速画等腰梯形
- 2022最全Hbuilder打包成苹果IOS-App的详解
- 打造一个生命周期感知的MVP架构
- crontab指定时间
- 天津师范大学计算机专业排名,天津最好的10所大学公布:天津师范大学第三,各校就业率相差较大...
- Three.js光照贴图添加阴影(·lightMap)
- MTK原厂,MT6771参考设计最新资料
- es文件浏览器有linux版么,【ES 文件浏览器】ES 文件浏览器TV版_ES 文件浏览器TV版官网_-沙发管家TV版应用市场...
- 如何构建供应链金融平台?这8大能力不可或缺!
- Electron的使用笔记之应用程序打开控制台
热门文章
- python递归列文件_python-Bash:从最大列递归地向文件写入一行
- c语言回溯算法骑士周游,191-骑士周游回溯算法代码实现(1)
- 结构专业规范大全_2019年一、二级注册结构师专业考试所用的规范、标准、规程...
- 交错字符串Python解法
- UE4学习-第三人称游戏的AI巡逻
- CentOS7命令(基本命令,新手入门)
- android 串口一直打开_实例 | 使用Python串口实时显示数据并绘图
- io多路复用的原理和实现_IO多路复用的三种机制:select 、poll 、epoll
- html css加载不了_CSS加载会阻塞页面显示?
- HDLBits答案(10)_D触发器、同步与异步复位、脉冲边沿检测