org.tio.utils.cache.LFUCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mica-net-utils Show documentation
Show all versions of mica-net-utils Show documentation
Mica net is a net framework.
package org.tio.utils.cache;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
/**
* LFU(least frequently used) 最少使用率缓存
* 根据使用次数来判定对象是否被持续缓存
* 使用率是通过访问次数计算的。
* 当缓存满时清理过期对象。
* 清理后依旧满的情况下清除最少访问(访问计数最小)的对象并将其他对象的访问数减去这个最小访问数,以便新对象进入后可以公平计数。
*
* @param 键类型
* @param 值类型
* @author Looly, jodd
*/
public class LFUCache extends StampedCache {
private static final long serialVersionUID = 1L;
/**
* 构造
*
* @param capacity 容量
*/
public LFUCache(int capacity) {
this(capacity, 0);
}
/**
* 构造
*
* @param capacity 容量
* @param timeout 过期时长
*/
public LFUCache(int capacity, long timeout) {
super(new HashMap<>(capacity + 1, 1.0f), capacity, timeout);
}
// ---------------------------------------------------------------- prune
/**
* 清理过期对象。
* 清理后依旧满的情况下清除最少访问(访问计数最小)的对象并将其他对象的访问数减去这个最小访问数,以便新对象进入后可以公平计数。
*
* @return 清理个数
*/
@Override
protected int pruneCache() {
int count = 0;
CacheObj comin = null;
// 清理过期对象并找出访问最少的对象
Iterator> values = cacheObjIter();
CacheObj co;
while (values.hasNext()) {
co = values.next();
if (co.isExpired()) {
values.remove();
onRemove(co.key, co.obj);
count++;
continue;
}
//找出访问最少的对象
if (comin == null || co.accessCount.get() < comin.accessCount.get()) {
comin = co;
}
}
// 减少所有对象访问量,并清除减少后为0的访问对象
if (isFull() && comin != null) {
long minAccessCount = comin.accessCount.get();
values = cacheObjIter();
CacheObj co1;
while (values.hasNext()) {
co1 = values.next();
if (co1.accessCount.addAndGet(-minAccessCount) <= 0) {
values.remove();
onRemove(co1.key, co1.obj);
count++;
}
}
}
return count;
}
}