All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.octo.android.robospice.persistence.memory.LruCacheObjectPersister Maven / Gradle / Ivy

The newest version!
package com.octo.android.robospice.persistence.memory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import roboguice.util.temp.Ln;

import com.octo.android.robospice.persistence.DurationInMillis;
import com.octo.android.robospice.persistence.ObjectPersister;
import com.octo.android.robospice.persistence.exception.CacheLoadingException;
import com.octo.android.robospice.persistence.exception.CacheSavingException;

/**
 * Abstract in-memory object persister, based on the Android LRUCache.
 * @author David Stemmer
 * @author Mike Jancola
 */
public class LruCacheObjectPersister extends ObjectPersister {
    private LruCache> lruCache;
    private ObjectPersister decoratedPersister;

    public LruCacheObjectPersister(Class clazz, LruCache> lruCache) {
        super(null, clazz);
        this.lruCache = lruCache;
    }

    public LruCacheObjectPersister(ObjectPersister decoratedPersister, LruCache> lruCache) {
        super(decoratedPersister.getApplication(), decoratedPersister.getHandledClass());
        this.decoratedPersister = decoratedPersister;
        this.lruCache = lruCache;
    }

    public ObjectPersister getDecoratedPersister() {
        return decoratedPersister;
    }

    public LruCache> getLruCache() {
        return lruCache;
    }

    @Override
    public T loadDataFromCache(Object cacheKey, long maxTimeInCacheBeforeExpiry) throws CacheLoadingException {
        CacheItem cacheItem = lruCache.get(cacheKey);

        if (cacheItem == null) {
            Ln.d("Miss from lru cache for %s", cacheKey);
            if (decoratedPersister != null) {
                T data = decoratedPersister.loadDataFromCache(cacheKey, maxTimeInCacheBeforeExpiry);
                if (data == null) {
                    return null;
                }
                CacheItem item = new CacheItem(decoratedPersister.getCreationDateInCache(cacheKey), data);
                Ln.d("Put in lru cache after miss");
                lruCache.put(cacheKey, item);
                return data;
            }
            return null;
        } else {
            Ln.d("Hit from lru cache for %s", cacheKey);
            boolean dataCanExpire = maxTimeInCacheBeforeExpiry != DurationInMillis.ALWAYS_RETURNED;
            boolean dataIsNotExpired = System.currentTimeMillis() - cacheItem.getCreationDate() <= maxTimeInCacheBeforeExpiry;
            if (!dataCanExpire || dataIsNotExpired) {
                return cacheItem.getData();
            }
            return null;
        }
    }

    @Override
    public T saveDataToCacheAndReturnData(T data, Object cacheKey) throws CacheSavingException {
        CacheItem itemToCache = new CacheItem(data);
        lruCache.put(cacheKey, itemToCache);
        Ln.d("Put in lru cache for %s", cacheKey);

        if (decoratedPersister != null) {
            decoratedPersister.saveDataToCacheAndReturnData(data, cacheKey);
        }

        return data;
    }

    @Override
    public boolean isDataInCache(Object cacheKey, long maxTimeInCacheBeforeExpiry) {
        CacheItem cacheItem = lruCache.get(cacheKey);

        if (cacheItem == null) {
            if (decoratedPersister != null) {
                return decoratedPersister.isDataInCache(cacheKey, maxTimeInCacheBeforeExpiry);
            }
            return false;
        } else {
            boolean dataCanExpire = maxTimeInCacheBeforeExpiry != DurationInMillis.ALWAYS_RETURNED;
            boolean dataIsNotExpired = System.currentTimeMillis() - cacheItem.getCreationDate() <= maxTimeInCacheBeforeExpiry;
            return !dataCanExpire || dataIsNotExpired;
        }
    }

    @Override
    public long getCreationDateInCache(Object cacheKey) throws CacheLoadingException {
        CacheItem cacheItem = lruCache.get(cacheKey);

        if (cacheItem != null) {
            return cacheItem.getCreationDate();
        } else {
            if (decoratedPersister != null) {
                return decoratedPersister.getCreationDateInCache(cacheKey);
            }
        }
        throw new CacheLoadingException("Data could not be found in cache for cacheKey=" + cacheKey);
    }

    @Override
    public List loadAllDataFromCache() throws CacheLoadingException {
        if (decoratedPersister != null) {
            return decoratedPersister.loadAllDataFromCache();
        } else {
            Map> cacheMap = lruCache.snapshot();
            List allData = new ArrayList();
            for (CacheItem item : cacheMap.values()) {
                allData.add(item.getData());
            }
            return allData;
        }
    }

    @Override
    public List getAllCacheKeys() {
        if (decoratedPersister != null) {
            return decoratedPersister.getAllCacheKeys();
        } else {
            return new ArrayList(lruCache.snapshot().keySet());
        }
    }

    @Override
    public boolean removeDataFromCache(Object cacheKey) {
        boolean result = false;
        if (decoratedPersister != null) {
            result = decoratedPersister.removeDataFromCache(cacheKey);
        }
        return result || lruCache.remove(cacheKey) != null;
    }

    @Override
    public void removeAllDataFromCache() {
        lruCache.evictAll();
        if (decoratedPersister != null) {
            decoratedPersister.removeAllDataFromCache();
        }
    }

}