com.github.ignition.support.cache
Class AbstractCache<KeyT,ValT>

java.lang.Object
  extended by com.github.ignition.support.cache.AbstractCache<KeyT,ValT>
All Implemented Interfaces:
Map<KeyT,ValT>
Direct Known Subclasses:
HttpResponseCache, ImageCache, ModelCache

public abstract class AbstractCache<KeyT,ValT>
extends Object
implements Map<KeyT,ValT>

A simple 2-level cache consisting of a small and fast in-memory cache (1st level cache) and an (optional) slower but bigger disk cache (2nd level cache). For disk caching, either the application's cache directory or the SD card can be used. Please note that in the case of the app cache dir, Android may at any point decide to wipe that entire directory if it runs low on internal storage. The SD card cache must be managed by the application, e.g. by calling #wipe whenever the app quits.

When pulling from the cache, it will first attempt to load the data from memory. If that fails, it will try to load it from disk (assuming disk caching is enabled). If that succeeds, the data will be put in the in-memory cache and returned (read-through). Otherwise it's a cache miss.

Pushes to the cache are always write-through (i.e. the data will be stored both on disk, if disk caching is enabled, and in memory).

Author:
Matthias Kaeppler

Nested Class Summary
 
Nested classes/interfaces inherited from interface java.util.Map
Map.Entry<K,V>
 
Field Summary
static int DISK_CACHE_INTERNAL
           
static int DISK_CACHE_SDCARD
           
protected  String diskCacheDirectory
           
 
Constructor Summary
AbstractCache(String name, int initialCapacity, long expirationInMinutes, int maxConcurrentThreads)
          Creates a new cache instance.
 
Method Summary
 void clear()
          Clears the entire cache (memory and disk).
 void clear(boolean removeFromDisk)
          Clears the memory cache, as well as the disk cache if it's enabled and removeFromDisk is true.
 boolean containsKey(Object key)
          Checks if a value is present in the cache.
 boolean containsKeyInMemory(Object key)
          Checks if a value is present in the in-memory cache.
 boolean containsKeyOnDisk(Object key)
          Checks if a value is present in the disk cache.
 boolean containsValue(Object value)
          Checks if the given value is currently held in memory.
 boolean enableDiskCache(android.content.Context context, int storageDevice)
          Enable caching to the phone's internal storage or SD card.
 Set<Map.Entry<KeyT,ValT>> entrySet()
           
 ValT get(Object elementKey)
          Reads a value from the cache by first probing the in-memory cache.
 List<File> getCachedFiles()
          Retrieves the list of files that are currently cached to disk.
 String getDiskCacheDirectory()
          Only meaningful if disk caching is enabled.
abstract  String getFileNameForKey(KeyT key)
          Only meaningful if disk caching is enabled.
 boolean isDiskCacheEnabled()
           
 boolean isEmpty()
           
 Set<KeyT> keySet()
           
 ValT put(KeyT key, ValT value)
          Writes an element to the cache.
 void putAll(Map<? extends KeyT,? extends ValT> t)
           
protected abstract  ValT readValueFromDisk(File file)
          Only meaningful if disk caching is enabled.
 ValT remove(Object key)
          Removes an entry from both memory and disk.
 ValT removeKey(Object key)
          Removes an entry from memory.
 void setDiskCacheEnabled(String rootDir)
           
 int size()
           
 Collection<ValT> values()
           
protected abstract  void writeValueToDisk(File file, ValT value)
          Only meaningful if disk caching is enabled.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface java.util.Map
equals, hashCode
 

Field Detail

DISK_CACHE_INTERNAL

public static final int DISK_CACHE_INTERNAL
See Also:
Constant Field Values

DISK_CACHE_SDCARD

public static final int DISK_CACHE_SDCARD
See Also:
Constant Field Values

diskCacheDirectory

protected String diskCacheDirectory
Constructor Detail

AbstractCache

public AbstractCache(String name,
                     int initialCapacity,
                     long expirationInMinutes,
                     int maxConcurrentThreads)
Creates a new cache instance.

Parameters:
name - a human readable identifier for this cache. Note that this value will be used to derive a directory name if the disk cache is enabled, so don't get too creative here (camel case names work great)
initialCapacity - the initial element size of the cache
expirationInMinutes - time in minutes after which elements will be purged from the cache
maxConcurrentThreads - how many threads you think may at once access the cache; this need not be an exact number, but it helps in fragmenting the cache properly
Method Detail

enableDiskCache

public boolean enableDiskCache(android.content.Context context,
                               int storageDevice)
Enable caching to the phone's internal storage or SD card.

Parameters:
context - the current context
storageDevice - where to store the cached files, either DISK_CACHE_INTERNAL or DISK_CACHE_SDCARD)
Returns:

getDiskCacheDirectory

public String getDiskCacheDirectory()
Only meaningful if disk caching is enabled. See enableDiskCache(android.content.Context, int).

Returns:
the full absolute path to the directory where files are cached, if the disk cache is enabled, otherwise null

getFileNameForKey

public abstract String getFileNameForKey(KeyT key)
Only meaningful if disk caching is enabled. See enableDiskCache(android.content.Context, int). Turns a cache key into the file name that will be used to persist the value to disk. Subclasses must implement this.

Parameters:
key - the cache key
Returns:
the file name

readValueFromDisk

protected abstract ValT readValueFromDisk(File file)
                                   throws IOException
Only meaningful if disk caching is enabled. See enableDiskCache(android.content.Context, int). Restores a value previously persisted to the disk cache.

Parameters:
file - the file holding the cached value
Returns:
the cached value
Throws:
IOException

writeValueToDisk

protected abstract void writeValueToDisk(File file,
                                         ValT value)
                                  throws IOException
Only meaningful if disk caching is enabled. See enableDiskCache(android.content.Context, int). Persists a value to the disk cache.

Parameters:
ostream - the file output stream (buffered).
value - the cache value to persist
Throws:
IOException

get

public ValT get(Object elementKey)
Reads a value from the cache by first probing the in-memory cache. If not found, the the disk cache will be probed. If it's a hit, the entry is written back to memory and returned.

Specified by:
get in interface Map<KeyT,ValT>
Parameters:
elementKey - the cache key
Returns:
the cached value, or null if element was not cached

put

public ValT put(KeyT key,
                ValT value)
Writes an element to the cache. NOTE: If disk caching is enabled, this will write through to the disk, which may introduce a performance penalty.

Specified by:
put in interface Map<KeyT,ValT>

putAll

public void putAll(Map<? extends KeyT,? extends ValT> t)
Specified by:
putAll in interface Map<KeyT,ValT>

containsKey

public boolean containsKey(Object key)
Checks if a value is present in the cache. If the disk cached is enabled, this will also check whether the value has been persisted to disk.

Specified by:
containsKey in interface Map<KeyT,ValT>
Parameters:
key - the cache key
Returns:
true if the value is cached in memory or on disk, false otherwise

containsKeyInMemory

public boolean containsKeyInMemory(Object key)
Checks if a value is present in the in-memory cache. This method ignores the disk cache.

Parameters:
key - the cache key
Returns:
true if the value is currently hold in memory, false otherwise

containsKeyOnDisk

public boolean containsKeyOnDisk(Object key)
Checks if a value is present in the disk cache. This method ignores the memory cache.

Parameters:
key - the cache key
Returns:
true if the value is currently hold on disk, false otherwise. Always false if disk cache is disabled.

containsValue

public boolean containsValue(Object value)
Checks if the given value is currently held in memory. For performance reasons, this method does NOT probe the disk cache.

Specified by:
containsValue in interface Map<KeyT,ValT>

remove

public ValT remove(Object key)
Removes an entry from both memory and disk.

Specified by:
remove in interface Map<KeyT,ValT>

removeKey

public ValT removeKey(Object key)
Removes an entry from memory.

Parameters:
key - the cache key
Returns:
the element removed or null

keySet

public Set<KeyT> keySet()
Specified by:
keySet in interface Map<KeyT,ValT>

entrySet

public Set<Map.Entry<KeyT,ValT>> entrySet()
Specified by:
entrySet in interface Map<KeyT,ValT>

size

public int size()
Specified by:
size in interface Map<KeyT,ValT>

isEmpty

public boolean isEmpty()
Specified by:
isEmpty in interface Map<KeyT,ValT>

isDiskCacheEnabled

public boolean isDiskCacheEnabled()

getCachedFiles

public List<File> getCachedFiles()
Retrieves the list of files that are currently cached to disk. Guarantees to never return null.

Returns:
the list of files on disk

setDiskCacheEnabled

public void setDiskCacheEnabled(String rootDir)
Parameters:
rootDir - a folder name to enable caching or null to disable it.

clear

public void clear()
Clears the entire cache (memory and disk).

Specified by:
clear in interface Map<KeyT,ValT>

clear

public void clear(boolean removeFromDisk)
Clears the memory cache, as well as the disk cache if it's enabled and removeFromDisk is true.

Parameters:
removeFromDisk - whether or not to wipe the disk cache, too

values

public Collection<ValT> values()
Specified by:
values in interface Map<KeyT,ValT>


Copyright © 2012. All Rights Reserved.