From 96485d132be4a5d1c038fc41b07fa686647a3817 Mon Sep 17 00:00:00 2001 From: godotg Date: Fri, 16 Aug 2024 17:58:02 +0800 Subject: [PATCH] fix[cache]: fixed a bug where expired data could not be deleted --- .../com/zfoo/scheduler/util/LazyCache.java | 17 +++++++++---- .../zfoo/scheduler/util/LazyCacheTesting.java | 24 ++++++++++++------- 2 files changed, 28 insertions(+), 13 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 2df52f807..b85a119a2 100644 --- a/scheduler/src/main/java/com/zfoo/scheduler/util/LazyCache.java +++ b/scheduler/src/main/java/com/zfoo/scheduler/util/LazyCache.java @@ -1,5 +1,6 @@ package com.zfoo.scheduler.util; +import com.zfoo.protocol.collection.CollectionUtils; import com.zfoo.protocol.model.Pair; import com.zfoo.protocol.util.AssertionUtils; @@ -123,6 +124,16 @@ private void removeForCause(K key, RemovalCause removalCause) { } } + private void removeForCause(List> list, RemovalCause removalCause) { + if (CollectionUtils.isEmpty(list)) { + return; + } + var removeList = list.stream() + .filter(it -> cacheMap.remove(it.getKey()) != null) + .toList(); + removeListener.accept(removeList, removalCause); + } + public void forEach(BiConsumer biConsumer) { for (var entry : cacheMap.entrySet()) { biConsumer.accept(entry.getKey(), entry.getValue().value); @@ -143,8 +154,7 @@ private void checkMaximumSize() { .limit(Math.max(0, cacheMap.size() - maximumSize)) .map(it -> new Pair<>(it.getKey(), it.getValue().value)) .toList(); - removeList.forEach(it -> cacheMap.remove(it.getKey())); - removeListener.accept(removeList, RemovalCause.SIZE); + removeForCause(removeList, RemovalCause.SIZE); } } @@ -166,8 +176,7 @@ private void checkExpire() { minTimestamp = expireTime; } } - removeList.forEach(it -> cacheMap.remove(it.getKey())); - removeListener.accept(removeList, RemovalCause.EXPIRED); + removeForCause(removeList, RemovalCause.EXPIRED); if (minTimestamp < Long.MAX_VALUE) { this.minExpireTime = minTimestamp; } diff --git a/scheduler/src/test/java/com/zfoo/scheduler/util/LazyCacheTesting.java b/scheduler/src/test/java/com/zfoo/scheduler/util/LazyCacheTesting.java index 4f964a0c3..4c72fe3d8 100644 --- a/scheduler/src/test/java/com/zfoo/scheduler/util/LazyCacheTesting.java +++ b/scheduler/src/test/java/com/zfoo/scheduler/util/LazyCacheTesting.java @@ -23,7 +23,7 @@ public class LazyCacheTesting { private static final BiConsumer>, LazyCache.RemovalCause> myRemoveCallback = new BiConsumer>, LazyCache.RemovalCause>() { @Override public void accept(List> pairs, LazyCache.RemovalCause removalCause) { - for(var pair : pairs) { + for (var pair : pairs) { logger.info("remove key:[{}] value:[{}] removalCause:[{}]", pair.getKey(), pair.getValue(), removalCause); } } @@ -46,8 +46,10 @@ public void putTest() { lazyCache.put(11, "k"); lazyCache.put(12, "l"); ThreadUtils.sleep(3000); + System.out.println("first ->"); lazyCache.put(13, "m"); ThreadUtils.sleep(3000); + System.out.println("second ->"); lazyCache.put(14, "n"); ThreadUtils.sleep(3000); } @@ -109,17 +111,18 @@ public void multipleThreadMaxSizeTest() { for (int i = 0; i < executors.length; i++) { executors[i] = Executors.newSingleThreadExecutor(); } - var lazyCache = new LazyCache(1_00, 10000000 * TimeUtils.MILLIS_PER_SECOND, 5 * TimeUtils.MILLIS_PER_SECOND, myRemoveCallback); + var lazyCache = new LazyCache(1_00, 10000000 * TimeUtils.MILLIS_PER_SECOND, 5 * TimeUtils.MILLIS_PER_SECOND, 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)); + while (true) { + for (int j = i1 * 1_0000; j < startIndex + 1_0000; j++) { + lazyCache.put(j, String.valueOf(j)); + } } } }); @@ -138,7 +141,7 @@ public void multipleThreadCheckIntervalTest() { 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); + var lazyCache = new LazyCache(1_0000, 10000000 * TimeUtils.MILLIS_PER_SECOND, 0, null); for (int i = 0; i < executors.length; i++) { var executor = executors[i]; @@ -147,8 +150,11 @@ public void multipleThreadCheckIntervalTest() { @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)); + while (true) { + for (int j = i1 * 1_0000; j < startIndex + 1_0000; j++) { + lazyCache.put(j, String.valueOf(j)); + } + } } }); @@ -197,7 +203,7 @@ public void multipleThreadNotExpiredTest() { for (int i = 0; i < executors.length; i++) { executors[i] = Executors.newSingleThreadExecutor(); } - var lazyCache = new LazyCache(1_0000, 100000 * TimeUtils.MILLIS_PER_SECOND, 5 * TimeUtils.MILLIS_PER_SECOND, myRemoveCallback); + var lazyCache = new LazyCache(1_0000, 100000 * TimeUtils.MILLIS_PER_SECOND, 5 * TimeUtils.MILLIS_PER_SECOND, null); for (int i = 0; i < executors.length; i++) { var executor = executors[i];