package com.snowcattle.game.common.util;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
/**
* 提供LRU算法的Map实现
*
*
* @param <K>
* @param <V>
*/
public class LRUHashMap<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = 1L;
/** 最大个数 */
private final int maxSize;
/** 淘汰策略 */
private transient final EvictPolicy<V> evictPolicy;
/** 命中次数 */
private long hitCount = 0;
/** 未命中次数 */
private long missCount = 0;
/** 默认的淘汰策略:总是淘汰 */
private transient final EvictPolicy<V> DEFAULT = new EvictPolicy<V>() {
@Override
public boolean evict(V value) {
return true;
}
};
public LRUHashMap(int maxSize, EvictPolicy<V> evictPolicy) {
super(10, 0.75f, true);
if (maxSize <= 0) {
throw new IllegalArgumentException("The max size must be >0");
}
if (evictPolicy != null) {
this.evictPolicy = evictPolicy;
} else {
this.evictPolicy = DEFAULT;
}
this.maxSize = maxSize;
}
@Override
public V get(Object key) {
final V _value = super.get(key);
if (_value != null) {
++hitCount;
} else {
++missCount;
}
return _value;
}
/**
* @return 命中的次数
*/
public long getHitCount() {
return hitCount;
}
/**
* @return 未命中的次数
*/
public long getMissCount() {
return missCount;
}
/**
* 取得命中率
*
* @return
*/
public float getHitRate() {
final long _hitCount = this.hitCount;
final long _missCount = this.missCount;
final long _total = _hitCount + _missCount;
if (_total == 0) {
return 0;
} else {
final double _hitCountD = _hitCount;
return (float) (_hitCountD / _total);
}
}
/**
* 获取LRUHashMap的统计信息
*
* @return
*/
public String getStatistics() {
return "cache size:" + size() + "/" + this.maxSize + ",hit:" + getHitCount() + ",miss:" + getMissCount() + ",hitRate:"
+ (int) (getHitRate() * 100) + "%";
}
@Override
protected boolean removeEldestEntry(Entry<K, V> eldest) {
if (this.size() <= maxSize) {
return false;
}
return this.evictPolicy.evict(eldest.getValue());
}
public static interface EvictPolicy<V> {
public boolean evict(V value);
}
}