From 6b62bda613c7c9567939d4825cad384e29697eed Mon Sep 17 00:00:00 2001 From: godotg Date: Mon, 25 Mar 2024 23:12:01 +0800 Subject: [PATCH] perf[cache]: expire check --- .../java/com/zfoo/orm/util/LazyCache.java | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/orm/src/main/java/com/zfoo/orm/util/LazyCache.java b/orm/src/main/java/com/zfoo/orm/util/LazyCache.java index 81d89e8d..8ae92d1d 100644 --- a/orm/src/main/java/com/zfoo/orm/util/LazyCache.java +++ b/orm/src/main/java/com/zfoo/orm/util/LazyCache.java @@ -51,21 +51,22 @@ public class LazyCache { private int maximumSize; private long expireAfterAccessMillis; - private long expireCheckInterval; - private AtomicLong expireCheckTimeAtomic; + private long expireCheckIntervalMillis; private volatile long minExpireTime; + private AtomicLong expireCheckTimeAtomic; private ConcurrentMap> cacheMap; - private BiConsumer, RemovalCause> removeCallback = (pair, removalCause) -> { + private BiConsumer, RemovalCause> removeListener = (pair, removalCause) -> { }; - public LazyCache(int maximumSize, long expireAfterAccessMillis, long expireCheckIntervalMillis, BiConsumer, RemovalCause> removeCallback) { + public LazyCache(int maximumSize, long expireAfterAccessMillis, long expireCheckIntervalMillis, BiConsumer, RemovalCause> removeListener) { this.maximumSize = maximumSize; this.expireAfterAccessMillis = expireAfterAccessMillis; - this.expireCheckInterval = expireCheckIntervalMillis; - this.expireCheckTimeAtomic = new AtomicLong(TimeUtils.now() + expireCheckInterval); + this.expireCheckIntervalMillis = expireCheckIntervalMillis; + this.minExpireTime = TimeUtils.now(); + this.expireCheckTimeAtomic = new AtomicLong(TimeUtils.now() + expireCheckIntervalMillis); this.cacheMap = new ConcurrentHashMap<>(Math.max(maximumSize / 16, 512)); - if (removeCallback != null) { - this.removeCallback = removeCallback; + if (removeListener != null) { + this.removeListener = removeListener; } } @@ -78,10 +79,9 @@ public class LazyCache { cacheValue.expireTime = TimeUtils.now(); var oldCacheValue = cacheMap.put(key, cacheValue); if (oldCacheValue != null) { - removeCallback.accept(new Pair<>(key, oldCacheValue.value), RemovalCause.REPLACED); + removeListener.accept(new Pair<>(key, oldCacheValue.value), RemovalCause.REPLACED); } checkMaximumSize(); - checkExpire(); } public V get(K key) { @@ -92,7 +92,7 @@ public class LazyCache { return null; } if (cacheValue.expireTime < TimeUtils.now()) { - remove(key, RemovalCause.EXPIRED); + removeForCause(key, RemovalCause.EXPIRED); return null; } cacheValue.expireTime = TimeUtils.now() + expireAfterAccessMillis; @@ -101,16 +101,16 @@ public class LazyCache { public void remove(K key) { - remove(key, RemovalCause.EXPLICIT); + removeForCause(key, RemovalCause.EXPLICIT); } - public void remove(K key, RemovalCause removalCause) { + private void removeForCause(K key, RemovalCause removalCause) { if (key == null) { return; } var cacheValue = cacheMap.remove(key); if (cacheValue != null) { - removeCallback.accept(new Pair<>(key, cacheValue.value), removalCause); + removeListener.accept(new Pair<>(key, cacheValue.value), removalCause); } } @@ -138,16 +138,14 @@ public class LazyCache { minTimestamp = entry.getValue().expireTime; } } - this.minExpireTime = minTimestamp; - remove(minKey, RemovalCause.SIZE); - checkMaximumSize(); + removeForCause(minKey, RemovalCause.SIZE); } private void checkExpire() { var now = TimeUtils.now(); var expireCheckTime = expireCheckTimeAtomic.get(); if (now > expireCheckTime) { - if (expireCheckTimeAtomic.compareAndSet(expireCheckTime, now + expireCheckInterval)) { + if (expireCheckTimeAtomic.compareAndSet(expireCheckTime, now + expireCheckIntervalMillis)) { if (now > this.minExpireTime) { var minTimestamp = Long.MAX_VALUE; var removeList = new ArrayList(); @@ -155,13 +153,16 @@ public class LazyCache { var expireTime = entry.getValue().expireTime; if (expireTime < now) { removeList.add(entry.getKey()); + continue; } if (expireTime < minTimestamp) { minTimestamp = expireTime; } } - removeList.forEach(it -> remove(it, RemovalCause.EXPIRED)); - this.minExpireTime = minTimestamp; + removeList.forEach(it -> removeForCause(it, RemovalCause.EXPIRED)); + if (this.minExpireTime < Long.MAX_VALUE) { + this.minExpireTime = minTimestamp; + } } } }