Skip to content

Commit

Permalink
perf[cache]: limit check cache size time
Browse files Browse the repository at this point in the history
  • Loading branch information
jaysunxiao committed Mar 27, 2024
1 parent 15dd47e commit 9ee797d
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions scheduler/src/main/java/com/zfoo/scheduler/util/LazyCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
public class LazyCache<K, V> {

private static final float DEFAULT_BACK_PRESSURE_FACTOR = 0.11f;
private static final long MILLIS_MAX_SIZE_CHECK_INTERVAL = 300;

private static class CacheValue<V> {
public volatile V value;
Expand Down Expand Up @@ -56,6 +57,7 @@ public static enum RemovalCause {
private long expireCheckIntervalMillis;
private volatile long minExpireTime;
private AtomicLong expireCheckTimeAtomic;
private AtomicLong sizeCheckTimeAtomic;
private ConcurrentMap<K, CacheValue<V>> cacheMap;
private BiConsumer<Pair<K, V>, RemovalCause> removeListener = (pair, removalCause) -> {
};
Expand All @@ -67,6 +69,7 @@ public LazyCache(int maximumSize, long expireAfterAccessMillis, long expireCheck
this.expireCheckIntervalMillis = expireCheckIntervalMillis;
this.minExpireTime = TimeUtils.now();
this.expireCheckTimeAtomic = new AtomicLong(TimeUtils.now() + expireCheckIntervalMillis);
this.sizeCheckTimeAtomic = new AtomicLong(TimeUtils.now());
this.cacheMap = new ConcurrentHashMap<>(Math.max(maximumSize / 16, 512));
if (removeListener != null) {
this.removeListener = removeListener;
Expand Down Expand Up @@ -130,15 +133,21 @@ public int size() {

// -----------------------------------------------------------------------------------------------------------------
private void checkMaximumSize() {
if (cacheMap.size() <= backPressureSize) {
if (cacheMap.size() < backPressureSize) {
return;
}
var exceedList = cacheMap.entrySet()
.stream()
.sorted((a, b) -> Long.compare(a.getValue().expireTime, b.getValue().expireTime))
.limit(cacheMap.size() - maximumSize)
.toList();
exceedList.forEach(it -> removeForCause(it.getKey(), RemovalCause.SIZE));
var now = TimeUtils.now();
var sizeCheckTime = sizeCheckTimeAtomic.get();
if (now > sizeCheckTime) {
if (sizeCheckTimeAtomic.compareAndSet(sizeCheckTime, now + MILLIS_MAX_SIZE_CHECK_INTERVAL)) {
var exceedList = cacheMap.entrySet()
.stream()
.sorted((a, b) -> Long.compare(a.getValue().expireTime, b.getValue().expireTime))
.limit(Math.max(0, cacheMap.size() - maximumSize))
.toList();
exceedList.forEach(it -> removeForCause(it.getKey(), RemovalCause.SIZE));
}
}
}

private void checkExpire() {
Expand Down

0 comments on commit 9ee797d

Please sign in to comment.