1 /* 2 * Copyright (c) 2013. Bump Technologies Inc. All Rights Reserved. 3 */ 4 5 package com.bumptech.glide.load.engine.cache; 6 7 import android.util.Log; 8 9 import com.bumptech.glide.disklrucache.DiskLruCache; 10 import com.bumptech.glide.load.Key; 11 12 import java.io.File; 13 import java.io.IOException; 14 15 /** 16 * The default DiskCache implementation. There must be no more than one active instance for a given 17 * directory at a time. 18 * 19 * @see #get(java.io.File, int) 20 */ 21 public class DiskLruCacheWrapper implements DiskCache { 22 private static final String TAG = "DiskLruCacheWrapper"; 23 24 private static final int APP_VERSION = 1; 25 private static final int VALUE_COUNT = 1; 26 private static DiskLruCacheWrapper wrapper = null; 27 28 private final SafeKeyGenerator safeKeyGenerator; 29 private final File directory; 30 private final int maxSize; 31 private DiskLruCache diskLruCache; 32 33 /** 34 * Get a DiskCache in the given directory and size. If a disk cache has alread been created with 35 * a different directory and/or size, it will be returned instead and the new arguments 36 * will be ignored. 37 * 38 * @param directory The directory for the disk cache 39 * @param maxSize The max size for the disk cache 40 * @return The new disk cache with the given arguments, or the current cache if one already exists 41 */ 42 public static synchronized DiskCache get(File directory, int maxSize) { 43 // TODO calling twice with different arguments makes it return the cache for the same directory, it's public! 44 if (wrapper == null) { 45 wrapper = new DiskLruCacheWrapper(directory, maxSize); 46 } 47 return wrapper; 48 } 49 50 protected DiskLruCacheWrapper(File directory, int maxSize) { 51 this.directory = directory; 52 this.maxSize = maxSize; 53 this.safeKeyGenerator = new SafeKeyGenerator(); 54 } 55 56 private synchronized DiskLruCache getDiskCache() throws IOException { 57 if (diskLruCache == null) { 58 diskLruCache = DiskLruCache.open(directory, APP_VERSION, VALUE_COUNT, maxSize); 59 } 60 return diskLruCache; 61 } 62 63 @Override 64 public File get(Key key) { 65 String safeKey = safeKeyGenerator.getSafeKey(key); 66 File result = null; 67 try { 68 //It is possible that the there will be a put in between these two gets. If so that shouldn't be a problem 69 //because we will always put the same value at the same key so our input streams will still represent 70 //the same data 71 final DiskLruCache.Value value = getDiskCache().get(safeKey); 72 if (value != null) { 73 result = value.getFile(0); 74 } 75 } catch (IOException e) { 76 if (Log.isLoggable(TAG, Log.WARN)) { 77 Log.w(TAG, "Unable to get from disk cache", e); 78 } 79 } 80 return result; 81 } 82 83 @Override 84 public void put(Key key, Writer writer) { 85 String safeKey = safeKeyGenerator.getSafeKey(key); 86 try { 87 DiskLruCache.Editor editor = getDiskCache().edit(safeKey); 88 // Editor will be null if there are two concurrent puts. In the worst case we will just silently fail. 89 if (editor != null) { 90 try { 91 File file = editor.getFile(0); 92 if (writer.write(file)) { 93 editor.commit(); 94 } 95 } finally { 96 editor.abortUnlessCommitted(); 97 } 98 } 99 } catch (IOException e) { 100 if (Log.isLoggable(TAG, Log.WARN)) { 101 Log.w(TAG, "Unable to put to disk cache", e); 102 } 103 } 104 } 105 106 @Override 107 public void delete(Key key) { 108 String safeKey = safeKeyGenerator.getSafeKey(key); 109 try { 110 getDiskCache().remove(safeKey); 111 } catch (IOException e) { 112 if (Log.isLoggable(TAG, Log.WARN)) { 113 Log.w(TAG, "Unable to delete from disk cache", e); 114 } 115 } 116 } 117 } 118