/* * Copyright (c) 2013. Bump Technologies Inc. All Rights Reserved. */ package com.bumptech.glide.load.engine.cache; import android.util.Log; import com.bumptech.glide.load.Key; import com.jakewharton.disklrucache.DiskLruCache; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * The default DiskCache implementation. There must be no more than one active instance for a given * directory at a time. * * @see #get(java.io.File, int) */ public class DiskLruCacheWrapper implements DiskCache { private static final String TAG = "DiskLruCacheWrapper"; private static final int APP_VERSION = 1; private static final int VALUE_COUNT = 1; private static DiskLruCacheWrapper WRAPPER = null; private final SafeKeyGenerator safeKeyGenerator; /** * Get a DiskCache in the given directory and size. If a disk cache has alread been created with * a different directory and/or size, it will be returned instead and the new arguments * will be ignored. * * @param directory The directory for the disk cache * @param maxSize The max size for the disk cache * @return The new disk cache with the given arguments, or the current cache if one already exists */ public synchronized static DiskCache get(File directory, int maxSize) { if (WRAPPER == null) { WRAPPER = new DiskLruCacheWrapper(directory, maxSize); } return WRAPPER; } private final File directory; private final int maxSize; private DiskLruCache diskLruCache; protected DiskLruCacheWrapper(File directory, int maxSize) { this.directory = directory; this.maxSize = maxSize; this.safeKeyGenerator = new SafeKeyGenerator(); } private synchronized DiskLruCache getDiskCache() throws IOException { if (diskLruCache == null) { diskLruCache = DiskLruCache.open(directory, APP_VERSION, VALUE_COUNT, maxSize); } return diskLruCache; } @Override public InputStream get(Key key) { String safeKey = safeKeyGenerator.getSafeKey(key); InputStream result = null; try { //It is possible that the there will be a put in between these two gets. If so that shouldn't be a problem //because we will always put the same value at the same key so our input streams will still represent //the same data final DiskLruCache.Snapshot snapshot = getDiskCache().get(safeKey); if (snapshot != null) { result = snapshot.getInputStream(0); } } catch (IOException e) { if (Log.isLoggable(TAG, Log.WARN)) { Log.w(TAG, "Unable to get from disk cache", e); } } return result; } @Override public void put(Key key, Writer writer) { String safeKey = safeKeyGenerator.getSafeKey(key); try { DiskLruCache.Editor editor = getDiskCache().edit(safeKey); //editor will be null if there are two concurrent puts //worst case just silently fail if (editor != null) { boolean success = false; OutputStream os = null; try { os = editor.newOutputStream(0); success = writer.write(os); } finally { if (os != null) { os.close(); } } if (success) { editor.commit(); } } } catch (IOException e) { if (Log.isLoggable(TAG, Log.WARN)) { Log.w(TAG, "Unable to put to disk cache", e); } } } @Override public void delete(Key key) { String safeKey = safeKeyGenerator.getSafeKey(key); try { getDiskCache().remove(safeKey); } catch (IOException e) { if (Log.isLoggable(TAG, Log.WARN)) { Log.w(TAG, "Unable to delete from disk cache", e); } } } }