Home | History | Annotate | Download | only in cache
      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