Mercurial > hg > LGDataverses
diff src/main/java/edu/harvard/iq/dataverse/util/LruCache.java @ 10:a50cf11e5178
Rewrite LGDataverse completely upgrading to dataverse4.0
| author | Zoe Hong <zhong@mpiwg-berlin.mpg.de> |
|---|---|
| date | Tue, 08 Sep 2015 17:00:21 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/edu/harvard/iq/dataverse/util/LruCache.java Tue Sep 08 17:00:21 2015 +0200 @@ -0,0 +1,88 @@ +package edu.harvard.iq.dataverse.util; + +import java.util.LinkedHashMap; +import java.util.concurrent.locks.ReentrantLock; + +/** + * A thread-safe implementation of a capped-size cache, where the removal is done + * based on the "Least Recently Used" strategy. + * This implementation allows some scenarios where the removed values are not the + * least recently used, in order to provide better performance. + * + * @author michael + * @param <K> Class for the cache keys + * @param <V> Class for the cache values + */ +public class LruCache<K,V> { + private final LinkedHashMap<K, V> cache = new LinkedHashMap<>(10, 0.75f, true); + private final ReentrantLock cacheLock = new ReentrantLock(); + private long maxSize = 128; + + /** + * @param k The key to get + * @return The value associated with {@code k}, or {@code null}, if there isn't any. + */ + public V get( K k ) { + try { + cacheLock.lock(); + return cache.get(k); + } finally { cacheLock.unlock(); } + } + + /** + * Associates {@code k} with {@code v}. + * @param k the key + * @param v the value + * @return {@code v}, to allow method call chaining. + */ + public V put( K k, V v ) { + try { + cacheLock.lock(); + cache.put(k, v); + shrinkToMaxSize(); + return v; + } finally { cacheLock.unlock(); } + } + + public long size() { + try { + cacheLock.lock(); + return cache.size(); + } finally { cacheLock.unlock(); } + } + + public long getMaxSize() { + return maxSize; + } + + public void setMaxSize(long maxSize) { + if ( maxSize < 1 ) { + throw new IllegalArgumentException("Max cache size can't be less than 1"); + } + try { + cacheLock.lock(); + this.maxSize = maxSize; + shrinkToMaxSize(); + } finally { cacheLock.unlock(); } + } + + public void invalidate() { + try { + cacheLock.lock(); + cache.clear(); + } finally { cacheLock.unlock(); } + } + + public void invalidate( K k ) { + try { + cacheLock.lock(); + cache.remove(k); + } finally { cacheLock.unlock(); } + } + + private void shrinkToMaxSize() { + while( cache.size() > getMaxSize() ) { + cache.remove( cache.entrySet().iterator().next().getKey() ); + } + } +}
