public class LazyRemovalCache<K,V> {
/**
* 缓存对象的hashMap
*/
private final ConcurrentMap<K,Entry<V>> map=new ConcurrentHashMap<K,Entry<V>>();
/** Max number of elements, if exceeded, we remove all elements marked as removable and older than max_age ms
* 缓存允许的最大条目
* */
private final int max_elements;
/**
* 缓存对象的最大生命周期
*/
private final long max_age;
/**
* 打印函数接口
* @author Administrator
*
* @param <K>
* @param <V>
*/
public interface Printable<K,V> {
String print(K key,V val);
}
/**
* 无参构造函数
*/
public LazyRemovalCache() {
this(200, 5000L);
}
/**
* 带参数的构造函数
* @param max_elements
* @param max_age
*/
public LazyRemovalCache(int max_elements, long max_age) {
this.max_elements=max_elements;
this.max_age=max_age;
}
/**
* 缓存中添加缓存对象
* @param key
* @param val
*/
public void add(K key, V val) {
if(key != null && val != null)
map.put(key, new Entry<V>(val)); // overwrite existing element (new timestamp, and possible removable mark erased)
checkMaxSizeExceeded();
}
/**
* 得到一个缓存对象
* @param key
* @return
*/
public V get(K key) {
if(key == null)
return null;
Entry<V> entry=map.get(key);
return entry != null? entry.val : null;
}
/**
* 根据缓存对象得到缓存KEY值
* @param val
* @return
*/
public K getByValue(V val) {
if(val == null) return null;
for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {
Entry<V> v=entry.getValue();
if(v.val != null && v.val.equals(val))
return entry.getKey();
}
return null;
}
/**
* 删除一个缓存对象
* @param key
*/
public void remove(K key) {
remove(key, false);
}
/**
* 删除缓存对象
* @param key
* @param force true:强制删除,false:非强制删除
*/
public void remove(K key, boolean force) {
if(key == null)
return;
if(force)
map.remove(key);
else {
Entry<V> entry=map.get(key);
if(entry != null)
entry.removable=true;
}
checkMaxSizeExceeded();
}
/**
* 删除一个集合的缓存的key值
* @param keys
*/
public void removeAll(Collection<K> keys) {
removeAll(keys, false);
}
public void removeAll(Collection<K> keys, boolean force) {
if(keys == null || keys.isEmpty())
return;
if(force)
map.keySet().removeAll(keys);
else {
for(K key: keys) {
Entry<V> entry=map.get(key);
if(entry != null)
entry.removable=true;
}
}
checkMaxSizeExceeded();
}
/**
* 清空缓存对象
* @param force true:强制清空,false:非强制清空
*/
public void clear(boolean force) {
if(force)
map.clear();
else {
for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {
Entry<V> val=entry.getValue();
if(val != null) {
Entry<V> tmp=entry.getValue();
if(tmp != null)
tmp.removable=true;
}
}
}
}
public void retainAll(Collection<K> keys) {
retainAll(keys, false);
}
/**
* 移除交集的key值
* @param keys
* @param force
*/
public void retainAll(Collection<K> keys, boolean force) {
if(keys == null || keys.isEmpty())
return;
if(force)
map.keySet().retainAll(keys);
else {
for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {
if(!keys.contains(entry.getKey())) {
Entry<V> val=entry.getValue();
if(val != null)
val.removable=true;
}
}
}
checkMaxSizeExceeded();
}
/**
* 得到Key值set数组
* @return
*/
public Set<V> values() {
Set<V> retval=new HashSet<V>();
for(Entry<V> entry: map.values()) {
retval.add(entry.val);
}
return retval;
}
/**
* 得到缓存的内容
* @return
*/
public Map<K,V > contents() {
Map<K,V> retval=new HashMap<K,V>();
for(Map.Entry<K,Entry<V>> entry: map.entrySet())
retval.put(entry.getKey(), entry.getValue().val);
return retval;
}
public int size() {
return map.size();
}
public String printCache() {
StringBuilder sb=new StringBuilder();
for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {
sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n");
}
return sb.toString();
}
public String printCache(Printable print_function) {
StringBuilder sb=new StringBuilder();
for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {
K key=entry.getKey();
V val=entry.getValue().val;
sb.append(print_function.print(key, val));
}
return sb.toString();
}
public String toString() {
return printCache();
}
private void checkMaxSizeExceeded() {
if(map.size() > max_elements) {
removeMarkedElements();
}
}
/**
* Removes elements marked as removable
* 删除掉被标志删除的元素
*
*/
public void removeMarkedElements() {
long curr_time=System.currentTimeMillis();
for(Iterator<Map.Entry<K,Entry<V>>> it=map.entrySet().iterator(); it.hasNext();) {
Map.Entry<K, Entry<V>> entry=it.next();
Entry<V> tmp=entry.getValue();
if(tmp.removable && (curr_time - tmp.timestamp) >= max_age) {
it.remove();
}
}
}
/**
*
* @author 缓存条目的封装类
*
* @param <V>
*/
private static class Entry<V> {
/**
* 缓存的对象
*/
private final V val;
/**
* 时间戳
*/
private final long timestamp=System.currentTimeMillis();
/**
* 是否被移除的标志
*/
private boolean removable=false;
public Entry(V val) {
this.val=val;
}
public String toString() {
return val + " (" + (System.currentTimeMillis() - timestamp) + "ms old" + (removable? ", removable" : "") + ")";
}
}
}