简析LRU
LRU
最近最少使用算法。
基本原理
-要求查找快,插入快,删除快,有顺序之分。哈希表查找快,但是数据无固定顺序;链表有顺序之分,插入删除快,但是查找慢。所以结合一下,形成一种新的数据结构:哈希链表。
按顺序插入 ,所以需要双向链表。
LinkedHashMap,使用 accessOrder=true 基于顺序访问,元素访问后被移动到末尾。
自己动手实现LRU
1 | class Node { |
LruCache
Android SDK里有提供。
DiskLruCache
Android SDK里没有提供,AOSP源码有。
很多文件操作都采用了事务的处理方式,即修改文件前先写入一个同名的 tmp 文件,当所有内容写完后再将 tmp 文件的扩展名去掉以覆盖原有文件,这样做的好处就是不会因为应用的异常退出或 Crash 而出现数据损坏,保证了原有文件的完整性。
DiskLruCache 在操作文件的时候使用 journal 文件 来记录操作日志。
journal头:
- 第一行是固定的字符串“libcore.io.DiskLruCache”,标志着使用的是DiskLruCache技术。
- 第二行是DiskLruCache的版本号。
- 第三行是应用程序的版本号。
- 第四行是valueCount
- 第五行是一个空行。
DIRTY 脏数据行 正在写入
CLEAN 洗净脏数据行 写入成功 行末尾加上该条缓存数据的大小,以字节为单位。
REMOVE 移除脏数据行 写入失败
READ 读取数据行
每一行DIRTY的key,后面都应该有一行对应的CLEAN或者REMOVE的记录,否则这条数据就是“脏”的。
redundantOpCount变量来记录用户操作的次数,每执行一次写入、读取或移除缓存的操作,这个变量值都会加1,当变量值达到2000的时候就会触发重构journal的事件,这时会自动把journal中一些多余的、不必要的记录全部清除掉,保证journal文件的大小始终保持在一个合理的范围内。