JakeWharton / DiskLruCache

Java implementation of a Disk-based LRU cache which specifically targets Android compatibility.
http://jakewharton.github.io/DiskLruCache
Apache License 2.0
5.79k stars 1.18k forks source link

Concurrent edit experience is cumbersome #19

Open swankjesse opened 12 years ago

swankjesse commented 12 years ago

We're using DiskLruCache in a serverside app that downloads images from a remote server. When two requests simultaneously want to store the same image in the cache, the code gets very ugly very fast. The problem is that edit() returns null and we have no mechanism to wait on the other editor's download to complete.

It would be handy if there was an API to await a snapshot that's currently being created.

I think it would be relatively straightforward to implement this on top of Guava's LoadingCache, but it would be simpler code to just do the blocking mechanics directly in DiskLruCache.

chrisbanes commented 11 years ago

The way I've implemented this is to keep a Map of ReentrantLocks. Feels a bit hacky but it seems to be working.

HashMap<String, ReentrantLock> mDiskCacheEditLocks = new HashMap<String, ReentrantLock>();

final ReentrantLock lock = getLockForDiskCacheEdit(key);
lock.lock();
try {
    DiskLruCache.Editor editor = mDiskCache.edit(key);
    // blah
    editor.commit();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    lock.unlock();
}

private ReentrantLock getLockForDiskCacheEdit(String key) {
    synchronized (mDiskCacheEditLocks) {
        ReentrantLock lock = mDiskCacheEditLocks.get(key);
        if (null == lock) {
            lock = new ReentrantLock();
            mDiskCacheEditLocks.put(key, lock);
        }
        return lock;
    }
}
virl commented 9 years ago

@chrisbanes uh what an ugly code. Why does this lib not supporting this from the box like TMCache? :(