From b3e61091a2be2944f9761b666669667062415eae Mon Sep 17 00:00:00 2001 From: godotg Date: Wed, 27 Mar 2024 17:48:48 +0800 Subject: [PATCH] perf[cache]: assert construct param --- .../com/zfoo/scheduler/util/LazyCache.java | 8 ++- .../zfoo/scheduler/util/LazyCacheTest.java | 59 +++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/scheduler/src/main/java/com/zfoo/scheduler/util/LazyCache.java b/scheduler/src/main/java/com/zfoo/scheduler/util/LazyCache.java index 155956b3b..252f23edf 100644 --- a/scheduler/src/main/java/com/zfoo/scheduler/util/LazyCache.java +++ b/scheduler/src/main/java/com/zfoo/scheduler/util/LazyCache.java @@ -2,6 +2,7 @@ import com.zfoo.protocol.model.Pair; import com.zfoo.protocol.model.PairLong; +import com.zfoo.protocol.util.AssertionUtils; import java.util.ArrayList; import java.util.concurrent.ConcurrentHashMap; @@ -62,12 +63,15 @@ public static enum RemovalCause { }; public LazyCache(int maximumSize, long expireAfterAccessMillis, long expireCheckIntervalMillis, BiConsumer, RemovalCause> removeListener) { + AssertionUtils.ge1(maximumSize); + AssertionUtils.ge0(expireAfterAccessMillis); + AssertionUtils.ge0(expireCheckIntervalMillis); this.maximumSize = maximumSize; this.backPressureSize = Math.max(maximumSize, maximumSize + (int) (maximumSize * DEFAULT_BACK_PRESSURE_FACTOR)); this.expireAfterAccessMillis = expireAfterAccessMillis; - this.expireCheckIntervalMillis = expireCheckIntervalMillis; + this.expireCheckIntervalMillis = Math.max(1, expireCheckIntervalMillis); this.minExpireTime = TimeUtils.now(); - this.expireCheckTimeAtomic = new AtomicLong(TimeUtils.now() + expireCheckIntervalMillis); + this.expireCheckTimeAtomic = new AtomicLong(TimeUtils.now()); this.cacheMap = new ConcurrentHashMap<>(Math.max(maximumSize / 16, 512)); if (removeListener != null) { this.removeListener = removeListener; diff --git a/scheduler/src/test/java/com/zfoo/scheduler/util/LazyCacheTest.java b/scheduler/src/test/java/com/zfoo/scheduler/util/LazyCacheTest.java index e7a4e05db..2df9a1332 100644 --- a/scheduler/src/test/java/com/zfoo/scheduler/util/LazyCacheTest.java +++ b/scheduler/src/test/java/com/zfoo/scheduler/util/LazyCacheTest.java @@ -129,6 +129,65 @@ public void run() { } } + // check interval test + @Test + public void multipleThreadCheckIntervalTest() { + int threadNum = Runtime.getRuntime().availableProcessors() + 1; + ExecutorService[] executors = new ExecutorService[threadNum]; + for (int i = 0; i < executors.length; i++) { + executors[i] = Executors.newSingleThreadExecutor(); + } + var lazyCache = new LazyCache(1_0000, 10000000 * TimeUtils.MILLIS_PER_SECOND, 0, myRemoveCallback); + for (int i = 0; i < executors.length; i++) { + + var executor = executors[i]; + int i1 = i; + executor.execute(new Runnable() { + @Override + public void run() { + var startIndex = i1 * 1_0000; + for (int j = i1 * 1_0000; j < startIndex + 1_0000; j++) { + lazyCache.put(j, String.valueOf(j)); + } + } + }); + } + for (int i = 0; i < 10000; i++) { + logger.info("cache size:[{}]", lazyCache.size()); + ThreadUtils.sleep(1000); + } + } + + // expire after access test + @Test + public void multipleThreadExpireAfterAccessTest() { + int threadNum = Runtime.getRuntime().availableProcessors() + 1; + ExecutorService[] executors = new ExecutorService[threadNum]; + for (int i = 0; i < executors.length; i++) { + executors[i] = Executors.newSingleThreadExecutor(); + } + var lazyCache = new LazyCache(1_0000, 0, 0, null); + for (int i = 0; i < executors.length; i++) { + + var executor = executors[i]; + int i1 = i; + executor.execute(new Runnable() { + @Override + public void run() { + var startIndex = i1 * 1_0000; + for (int j = i1 * 1_0000; j < startIndex + 1_0000; j++) { + lazyCache.put(j, String.valueOf(j)); + } + } + }); + } + for (int i = 0; i < 10000; i++) { + lazyCache.get(-1); + logger.info("cache size:[{}]", lazyCache.size()); + ThreadUtils.sleep(100); + } + } + // not expired test @Test public void multipleThreadNotExpiredTest() {