简单LRU算法实现缓存大小的限制策略

参考:Android-Universal-Image-Loader

private final Map<File, Long> mLastUsageDates = Collections.synchronizedMap(new HashMap<File, Long>());
private final AtomicInteger mCacheSize;
private final int SIZE_LIMIT = 10 * 1024 * 1024;

{
        mCacheSize = new AtomicInteger();
        calculateCacheSizeAndFillUsageMap();
}

{
            saveImage(name);
            putImage(name);
}

    private void calculateCacheSizeAndFillUsageMap() {
    	new Thread(new Runnable() {
			@Override
			public void run() {
				int size = 0;
				File imageDir = new File(DIR_IMAGE);
				File[] cachedFiles = imageDir.listFiles();
				if(cachedFiles != null){
					for(File cachedFile : cachedFiles){
						size += cachedFile.length();
						mLastUsageDates.put(cachedFile, cachedFile.lastModified());
					}
					mCacheSize.set(size);
				}
			}
		}).start();
    }

    private void putImage(String path){
    	if(path == null)
    		return;
    	File imageFile = new File(path);
    	if(!imageFile.exists())
    		return;
    	int valueSize = (int)imageFile.length();
    	int curCacheSize = mCacheSize.get();
    	while (curCacheSize + valueSize > SIZE_LIMIT) {
    		int freedSize = removeMostLongUsedFile();
    		if (freedSize == -1)
    			break;
    		curCacheSize = mCacheSize.addAndGet(-freedSize);
    	}
    	mCacheSize.addAndGet(valueSize);
    	mLastUsageDates.put(imageFile, imageFile.lastModified());
    }

    private int removeMostLongUsedFile(){
		if (mLastUsageDates.isEmpty()) {
			return -1;
		}
		Long oldestUsage = null;
		File mostLongUsedFile = null;
		Set<Entry<File, Long>> entries = mLastUsageDates.entrySet();
		synchronized (mLastUsageDates) {
			for (Entry<File, Long> entry : entries) {
				if (mostLongUsedFile == null) {
					mostLongUsedFile = entry.getKey();
					oldestUsage = entry.getValue();
				} else {
					Long lastValueUsage = entry.getValue();
					if (lastValueUsage < oldestUsage) {
						oldestUsage = lastValueUsage;
						mostLongUsedFile = entry.getKey();
					}
				}
			}
		}

		int fileSize = 0;
		if (mostLongUsedFile != null) {
			if (mostLongUsedFile.exists()) {
				fileSize = (int)mostLongUsedFile.length();
				if (mostLongUsedFile.delete()) {
					mLastUsageDates.remove(mostLongUsedFile);
				}
			} else {
				mLastUsageDates.remove(mostLongUsedFile);
			}
		}
		return fileSize;
    }
时间: 2024-11-09 00:43:05

简单LRU算法实现缓存大小的限制策略的相关文章

LinkedHashMap 和 LRU算法实现

个人觉得LinkedHashMap 存在的意义就是为了实现 LRU 算法. public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> { public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) { super(initialCapacity, loadFactor); this.

缓存淘汰算法--LRU算法

1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是"如果数据最近被访问过,那么将来被访问的几率也更高". 1.2. 实现 最常见的实现是使用一个链表保存缓存数据,详细算法实现如下: 1. 新数据插入到链表头部: 2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部: 3. 当链表满的时候,将链表尾部的数据丢弃. 1.3. 分析 [命中率] 当存在热点数据时,LRU的效率很好,但偶发性的

Android探索之图片缓存&lt;Lru算法&gt;(二)

前言: 上篇我们总结了Bitmap的处理,同时对比了各种处理的效率以及对内存占用大小.我们得知一个应用如果使用大量图片就会导致OOM(out of memory),那该如何处理才能近可能的降低oom发生的概率呢?之前我们一直在使用SoftReference软引用,SoftReference是一种现在已经不再推荐使用的方式,因为从 Android 2.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用变得不再可靠,所以今天我们来认识一种新的缓存处理算法

【Java/Android性能优 4】PreloadDataCache支持预取的数据缓存,使用简单,支持多种缓存算法,支持不同网络类型,扩展性强

本文转自:http://www.trinea.cn/android/preloaddatacache/ 本文主要介绍一个支持自动向前或向后获取新数据的缓存的使用及功能.Android图片内存缓存可见ImageCache. 主要特性:(1).使用简单  (2).可自动预取新数据  (3).可选择多种缓存算法(包括FIFO.LIFO.LRU.MRU.LFU.MFU等15种)或自定义缓存算法  (4).省流量性能佳(有且仅有一个线程获取数据)  (5).支持不同类型网络处理  (6)缓存可序列化到本地

[转]缓存、缓存算法和缓存框架简单介绍

引言 我们都听过 cache,当你问他们是什么是缓存的时候,他们会给你一个完美的答案.可是他们不知道缓存是怎么构建的.或者没有告诉你应该採用什么标准去选择缓存框架. 在这边文章,我们会去讨论缓存.缓存算法.缓存框架以及哪个缓存框架会更好. 面试 "缓存就是存贮数据(使用频繁的数据)的暂时地方,由于取原始数据的代价太大了.所以我能够取得快一些." 这就是 programmer one (programmer one 是一个面试者)在面试中的回答(一个月前,他向公司提交了简历,想要应聘要求

缓存置换策略-LRU算法

LRU算法 LRU算法定义: LRU算法是指最近最少使用算法,意思是LRU认为最近使用过的数据,将来被访问的概率会大,最近没有被访问的数据意味着以后刚问的概率小. 为何要用LRU算法: 1.我们的存储空间是有限的,当存储空间满了之后,要删除哪些数据呢,才能会时缓存的命中率高一些呢 2.LRU算法还是比较简单的. 算法: 最常见的算法是使用一个链表来实现 1)将新数据插入到表头 2)每当缓存命中时,将数据移动到表头 3)当l存储空间满了的时候将链表尾部的数据删除 缺点:链表实现,需要遍历链表找到命

关于LRU算法(转载)

原文地址: http://flychao88.iteye.com/blog/1977653 http://blog.csdn.net/cjfeii/article/details/47259519 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是"如果数据最近被访问过,那么将来被访问的几率也更高". 1.2.实现 最常见的实现是使用一个链表保存缓存数据,详细算法实现如下: 1. 新数据插入到链表头部: 2. 每当缓存命

本地应用缓存算法和缓存策略的介绍

特别声明:该文章是 本人在网上搜索到的一些资料,稍作整理而成的,还望大家不要误会,具体出自于那本人也已经忘记.还请大家不要误会!!!   通过设计良好的数据分块.预取.替换.更新等算法来提高对缓存内容的命中率和一致性. 1)数据分块      Memcached默认情况下采用了名为Slab Allocator的机制分配.管理内存.在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的.但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操

LRU算法的Python实现

LRU:least recently used,最近最少使用算法.它的使用场景是:在有限的空间中存储对象时,当空间满时,会一定的原则删除原有的对象,常用的原则(算法)有LRU,FIFO,LFU等.在计算机的Cache硬件,以及主存到虚拟内存的页面置换,还有Redis缓存系统中都用到了该算法.我在一次面试和一个笔试时,都遇到过这个问题. LRU的算法是比较简单的,当对key进行访问时(一般有查询,更新,增加,在get()和set()两个方法中实现即可)时,将该key放到队列的最前端(或最后端)就行