This is an automated email from the ASF dual-hosted git repository. kezhuw pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/zookeeper.git
The following commit(s) were added to refs/heads/master by this push: new db8fe9c24 ZOOKEEPER-4919: Make ResponseCache a LRU as it supposed to be db8fe9c24 is described below commit db8fe9c241942e2222271acc8bbb9321c7a4957d Author: mikkosc <ext-mtiiho...@supercell.com> AuthorDate: Sat Apr 19 19:58:31 2025 +0300 ZOOKEEPER-4919: Make ResponseCache a LRU as it supposed to be Reviewers: tisonkun, kezhuw Author: mikkosc Closes #2243 from mikkosc/fix-lru-cache --- .../org/apache/zookeeper/server/ResponseCache.java | 18 ++++++++-------- .../{ => quorum}/FollowerRequestProcessorTest.java | 0 .../apache/zookeeper/test/ResponseCacheTest.java | 24 ++++++++++++++++++++-- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/ResponseCache.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/ResponseCache.java index 5c74caa12..4a1f87d49 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/ResponseCache.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/ResponseCache.java @@ -33,8 +33,13 @@ public class ResponseCache { public static final int DEFAULT_RESPONSE_CACHE_SIZE = 400; private final int cacheSize; private static class Entry { - public Stat stat; - public byte[] data; + public final Stat stat; + public final byte[] data; + + Entry(Stat stat, byte[] data) { + this.stat = stat; + this.data = data; + } } private final Map<String, Entry> cache; @@ -50,10 +55,7 @@ public int getCacheSize() { } public void put(String path, byte[] data, Stat stat) { - Entry entry = new Entry(); - entry.data = data; - entry.stat = stat; - cache.put(path, entry); + cache.put(path, new Entry(stat, data)); } public byte[] get(String key, Stat stat) { @@ -76,10 +78,10 @@ public boolean isEnabled() { private static class LRUCache<K, V> extends LinkedHashMap<K, V> { - private int cacheSize; + private final int cacheSize; LRUCache(int cacheSize) { - super(cacheSize / 4); + super(cacheSize / 4, 0.75f, true); this.cacheSize = cacheSize; } diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/server/FollowerRequestProcessorTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/server/quorum/FollowerRequestProcessorTest.java similarity index 100% rename from zookeeper-server/src/test/java/org/apache/zookeeper/server/FollowerRequestProcessorTest.java rename to zookeeper-server/src/test/java/org/apache/zookeeper/server/quorum/FollowerRequestProcessorTest.java diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ResponseCacheTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ResponseCacheTest.java index 4b1639405..32af00ae8 100644 --- a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ResponseCacheTest.java +++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ResponseCacheTest.java @@ -79,6 +79,7 @@ public void performCacheTest(ZooKeeper zk, String path, boolean useCache) throws Stat writeStat = new Stat(); Stat readStat = new Stat(); byte[] readData = null; + int cacheSize = Integer.getInteger(ZooKeeperServer.GET_DATA_RESPONSE_CACHE_SIZE); int reads = 10; long expectedHits = 0; long expectedMisses = 0; @@ -88,7 +89,7 @@ public void performCacheTest(ZooKeeper zk, String path, boolean useCache) throws LOG.info("caching: {}", useCache); if (useCache) { - assertEquals(zks.getReadResponseCache().getCacheSize(), 32); + assertEquals(zks.getReadResponseCache().getCacheSize(), cacheSize); assertEquals(zks.getGetChildrenResponseCache().getCacheSize(), 64); } @@ -146,15 +147,21 @@ public void performCacheTest(ZooKeeper zk, String path, boolean useCache) throws createPath(path + "/a/b/e/g", zk); createPath(path + "/a/b/e/h", zk); + createPath(path + "/x", zk); + for (int i = 0; i < cacheSize * 2; ++i) { + createPath(path + "/x/y" + i, zk); + } + checkPath(path + "/a", zk, 2); checkPath(path + "/a/b", zk, 2); checkPath(path + "/a/c", zk, 0); checkPath(path + "/a/b/d", zk, 0); checkPath(path + "/a/b/e", zk, 3); checkPath(path + "/a/b/e/h", zk, 0); + checkPath(path + "/x", zk, cacheSize * 2); if (useCache) { - expectedMisses += 6; + expectedMisses += 7; } checkCacheStatus(expectedHits, expectedMisses, "response_packet_get_children_cache_hits", @@ -170,6 +177,19 @@ public void performCacheTest(ZooKeeper zk, String path, boolean useCache) throws checkCacheStatus(expectedHits, expectedMisses, "response_packet_get_children_cache_hits", "response_packet_get_children_cache_misses"); + + for (int i = 0; i < cacheSize * 2; ++i) { + checkPath(path + "/a", zk, 2); + checkPath(path + "/x/y" + i, zk, 0); + + if (useCache) { + expectedHits += 1; + expectedMisses += 1; + } + + checkCacheStatus(expectedHits, expectedMisses, "response_packet_get_children_cache_hits", + "response_packet_get_children_cache_misses"); + } } private void createPath(String path, ZooKeeper zk) throws Exception {