All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gitee.apanlh.util.cache.local.CacheLruTwoQ Maven / Gradle / Ivy

There is a newer version: 2.0.0.2
Show newest version
package com.gitee.apanlh.util.cache.local;

import com.gitee.apanlh.util.base.Empty;
import com.gitee.apanlh.util.valid.ValidParam;

/**	
 * 	CacheTwoQ
 * 	
CacheLRU-2(Two queues 2Q) *
历史队列(采用FIFO的淘汰策略)和缓存队列(采用LRU-1的淘汰策略) *
新访问的数据插入到FIFO队列 *
如果数据在FIFO队列中一直没有被再次访问,则最终按照FIFO规则淘汰 *
如果数据在FIFO队列中被再次访问,则将数据移到LRU队列 *
如果数据在LRU队列再次被访问,则将数据移到LRU队尾 *
超出既定长度则 LRU队列淘汰中队头数据 * * @author Pan */ public class CacheLruTwoQ extends CacheAbstract { /** FIFO队列 */ private CacheFifo> a1; /** LRU队列 */ private CacheLru> a2; /** 命中次数 */ private int hit; /** * 默认构造函数 *
默认256最大容量 * * @author Pan */ public CacheLruTwoQ() { this(256, 256); } /** * 构造函数 *
默认A1与A2容量一致 *
自定义容量 * * @author Pan * @param capacity 容量 */ public CacheLruTwoQ(int capacity) { this(capacity, capacity); } /** * 构造函数 *
自定义FIFO,LRU长度 *
A1比例大则命中率降低,A1比例小则数据时间变长 * * @author Pan * @param a1Capacity a1容量 * @param a2Capacity a2容量 */ public CacheLruTwoQ(int a1Capacity, int a2Capacity) { super(Empty.map()); this.a1 = new CacheFifo<>(a1Capacity); this.a2 = new CacheLru<>(a2Capacity); } /** * 添加值 *
新访问的数据插入到FIFO队列(a1) 插入队尾; * * @author Pan * @param key 键 * @param value 值 * @return V */ @Override V putHandler(K key, V value) { CacheObject a2CacheObject = a2.getUnlocked(key); // 避免key值一样获取到的缓存数据为旧缓存 if (ValidParam.isNotNull(a2CacheObject)) { a2CacheObject.setData(value); } else { this.a1.putUnlocked(key, new CacheObject<>(value)); } return null; } @Override V getHandler(K key, V value) { // 优先对LRU检索 V v = getA2(key); // 二次检查 return v == null ? getA1(key) : v; } /** * 获取A1缓存数据 * * @author Pan * @param key 键 * @return V */ V getA1(K key) { CacheObject v = this.a1.getUnlocked(key); if (v == null) { return null; } hit++; // 删除FIFO中数据 this.a1.removeUnlocked(key); // 如果数据在FIFO队列中被再次访问,默认将数据移到LRU队列插入队尾 this.a2.putUnlocked(key, v); return v.getData(); } /** * 获取A2缓存数据 * * @author Pan * @param key 键 * @return V */ V getA2(K key) { CacheObject v = this.a2.getUnlocked(key); if (v == null) { return null; } hit++; return v.getData(); } /** * 清理A1缓存及A2缓存 *
两者缓存都会清空 * * @author Pan */ @Override public void clear() { lock(this::clearUnlock); } @Override public void clearUnlock() { a1.clearUnlock(); a2.clearUnlock(); } /** * 获取总长度 * * @author Pan * @return int */ @Override public int size() { return getA1Size() + getA2Size(); } /** * 获取a1长度 * * @author Pan * @return int */ public int getA1Size() { return this.a1.size(); } /** * 获取a2长度 * * @author Pan * @return int */ public int getA2Size() { return this.a2.size(); } /** * 获取FIFO缓存命中次数 * * @author Pan * @return int */ public int getA1Hit() { return this.a1.getHit(); } /** * 获取LRU缓存命中次数 * * @author Pan * @return int */ public int getA2Hit() { return this.a2.getHit(); } /** * 获取TwoQ缓存命中次数 *
非FIFO+LRU的缓存次数 * * @author Pan * @return int */ @Override public int getHit() { return this.hit; } /** * 获取A1缓存 * * @author Pan * @return CacheFifo */ public CacheFifo> getA1() { return this.a1; } /** * 获取A2缓存 * * @author Pan * @return CacheLru */ public CacheLru> getA2() { return this.a2; } @Override public String toString() { return "LRU2[FIFO=" + this.a1 + ", LRU=" + this.a2 + "]"; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; if (!super.equals(o)) return false; CacheLruTwoQ that = (CacheLruTwoQ) o; if (!a1.equals(that.a1)) return false; return a2.equals(that.a2); } @Override public int hashCode() { int result = super.hashCode(); result = 31 * result + a1.hashCode(); result = 31 * result + a2.hashCode(); return result; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy