com.gitee.apanlh.util.cache.local.CacheLfu Maven / Gradle / Ivy
package com.gitee.apanlh.util.cache.local;
import com.gitee.apanlh.util.base.MapUtils;
import java.util.Iterator;
/**
* LFU缓存
*
淘汰最少使用次数
*
* @author Pan
*/
public class CacheLfu extends CacheAbstract {
/** 最大容量 */
private int capacity;
/** 命中次数 */
private int hit;
/**
* 默认构造函数
*
默认256最大容量
*
* @author Pan
*/
public CacheLfu() {
this(256);
}
/**
* 构造函数
*
自定义容量
*
* @author Pan
* @param capacity 容量
*/
public CacheLfu(int capacity) {
super(MapUtils.newLinkedHashMap(capacity));
this.capacity = capacity;
}
@Override
@SuppressWarnings("unchecked")
V putHandler(K key, V value) {
V v = getMap().get(key);
// 队列不存在记录
if (v == null) {
// 如果容量达到上限时移除最小访问次数节点
if (size() == this.capacity) {
clearCache();
}
return (V) new CacheObject(value);
}
// 刷新缓存值并返回
return (V) flushCache((CacheObject) v, value);
}
@SuppressWarnings("unchecked")
@Override
V getHandler(K key, V value) {
if (value == null) {
return value;
}
hit++;
CacheObject cacheObject = (CacheObject) value;
// 添加访问次数
cacheObject.setCount();
return cacheObject.getData();
}
/**
* 淘汰访问次数最少且最久以前的数据
*
队列中存在节点数据信息,淘汰访问次数最少的数据
*
* @author Pan
*/
@SuppressWarnings("unchecked")
@Override
public void clearCache() {
Iterator iterator = values().iterator();
int minCount = -1;
while (iterator.hasNext()) {
CacheObject next = (CacheObject) iterator.next();
int count = next.getCount();
// 找到访问次数最少的队列数据
if (minCount == -1 || count < minCount) {
minCount = count;
}
}
if (size() == this.capacity) {
// 淘汰访问次数最少的数据
iterator = values().iterator();
while (iterator.hasNext()) {
CacheObject cacheObject = (CacheObject) iterator.next();
int historyCount = cacheObject.getCount();
// 从队列顶部开始检索访问次数等于检索到的最小访问次数
if (historyCount == minCount) {
iterator.remove();
}
// 避免清理队尾数据,清理队列顶部一半最小访问次数数据
if (size() <= (this.capacity / 2)) {
return ;
}
}
}
}
/**
* 刷新缓存值
*
* @author Pan
* @param cacheObject 缓存对象
* @param value 值
*/
private CacheObject flushCache(CacheObject cacheObject, V value) {
// 如果已存在缓存中更新缓存值
if (!cacheObject.getData().equals(value)) {
cacheObject.setData(value);
}
// 更新访问次数
cacheObject.setCount();
return cacheObject;
}
@Override
public String toString() {
return getMap().toString();
}
@Override
public int getHit() {
return this.hit;
}
@Override
public boolean equals(Object o) {
return super.equals(o);
}
@Override
public int hashCode() {
return super.hashCode();
}
}