LRUCache.java [src/csip/utils] Revision: Date:
/*
* $Id$
*
* This file is part of the Cloud Services Integration Platform (CSIP),
* a Model-as-a-Service framework, API and application suite.
*
* 2012-2022, Olaf David and others, OMSLab, Colorado State University.
*
* OMSLab licenses this file to you under the MIT license.
* See the LICENSE file in the project root for more information.
*/
package csip.utils;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* LRU cache.
*
* @author od
*/
public class LRUCache<K, V> {
static final int DEFAULT_SIZE = 16;
Map<K, V> m;
int size;
K k;
V v;
/**
* Create a LRU cache,
*
* @param size the cache size. A value of 0 disables the cache, a negative
* value throws an IllegalArgumentException.
*/
public LRUCache(int size) {
if (size < 0)
throw new IllegalArgumentException("size >= 0!");
m = new LinkedHashMap<>(size);
this.size = size;
}
/**
* Create a LRU cache with a default cache size of 16.
*/
public LRUCache() {
this(DEFAULT_SIZE);
}
public V put(K key, V val) {
if (size == 0 || key == null)
return null;
V prev = m.put(k = key, v = val);
prune();
return prev;
}
public V get(K key) {
if (size == 0 || key == null)
return null;
// accessing the last one again?
if (key.equals(k))
return v;
if (m.containsKey(key)) {
V val = m.get(key);
// remove it from wherever it is in the cache
m.remove(key);
// put it at top
m.put(k = key, v = val);
return val;
}
return null;
}
public void clear() {
m.clear();
k = null;
v = null;
}
public void setSize(int size) {
if (size < 0)
throw new IllegalArgumentException("cache size: " + size);
this.size = size;
prune();
}
public int getSize() {
return size;
}
private void prune() {
while (m.size() > size) {
// evict element
K first = m.keySet().iterator().next();
m.remove(first);
}
}
}