diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerCache.java b/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerCache.java index ae3a297b3..fb3e2fc22 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerCache.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerCache.java @@ -255,7 +255,7 @@ public class DefaultServerCache implements ServerCache { it.remove(); trimmedByTTL++; } else if (trimForMaxSize > 0) { - activeList.add(cacheEntry); + activeList.add(cacheEntry.forSort()); } } if (trimForMaxSize > 0 && activeList.size() > maxSize) { @@ -293,7 +293,7 @@ public class DefaultServerCache implements ServerCache { } /** - * Comparator for sorting by last access time. + * Comparator for sorting by last access sort, a copy of last access time that should not mutate during trim processing. */ public static final class CompareByLastAccess implements Comparator, Serializable { @@ -301,7 +301,7 @@ public class DefaultServerCache implements ServerCache { @Override public int compare(CacheEntry e1, CacheEntry e2) { - return Long.compare(e1.getLastAccessTime(), e2.getLastAccessTime()); + return Long.compare(e1.lastAccessSort, e2.lastAccessSort); } } @@ -314,6 +314,7 @@ public class DefaultServerCache implements ServerCache { private final Object value; private final long createTime; private long lastAccessTime; + private long lastAccessSort; public CacheEntry(Object key, Object value) { this.key = key; @@ -322,6 +323,14 @@ public class DefaultServerCache implements ServerCache { this.lastAccessTime = createTime; } + /** + * Store a copy of lastAccessTime used for sorting. This value should not change during trim processing. + */ + public CacheEntry forSort() { + this.lastAccessSort = lastAccessTime; + return this; + } + /** * Return the entry key. */ diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/cache/DefaultServerCache_RunEvictionTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/cache/DefaultServerCache_RunEvictionTest.java index c6596e6d8..236984ef8 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/cache/DefaultServerCache_RunEvictionTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/cache/DefaultServerCache_RunEvictionTest.java @@ -10,13 +10,11 @@ import org.junit.jupiter.api.Test; import java.util.Random; -public class DefaultServerCache_RunEvictionTest { - +class DefaultServerCache_RunEvictionTest { private DefaultServerCache createCache() { - ServerCacheOptions cacheOptions = new ServerCacheOptions(); - cacheOptions.setMaxSize(10000); + cacheOptions.setMaxSize(300); cacheOptions.setMaxIdleSecs(1); cacheOptions.setMaxSecsToLive(2); cacheOptions.setTrimFrequency(1); @@ -35,8 +33,7 @@ public class DefaultServerCache_RunEvictionTest { @Disabled("test takes long time") @Test - public void runEvict() throws InterruptedException { - + void runEvict() throws InterruptedException { for (int i = 0; i < 15; i++) { doStuff(); cache.runEviction(); @@ -47,10 +44,8 @@ public class DefaultServerCache_RunEvictionTest { } private void doStuff() { - for (int i = 0; i < 500; i++) { String key = "" + random.nextInt(20000); - int mode = random.nextInt(10); if (mode < 8) { cache.get(key);