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

来源:互联网 发布:sql minus 但不去重 编辑:程序博客网 时间:2024/04/30 15:00

参考: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() {@Overridepublic 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;    }


0 0