首页 > 代码库 > 简单LRU算法实现缓存大小的限制策略

简单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;
    }


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