diff --git a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java index 2d98fdb37d2..a05e464417a 100644 --- a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java +++ b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java @@ -275,7 +275,15 @@ public V computeIfAbsent(K key, IOFunction mappingFuncti public V put(K key, V val) { inserts.increment(); V old = cache.asMap().put(key, val); - recordRamBytes(key, old, val); + // ramBytes decrement for `old` happens via #onRemoval + if (val != old) { + // NOTE: this is conditional on `val != old` in order to work around a + // behavior in the Caffeine library: where there is reference equality + // between `val` and `old`, caffeine does _not_ invoke RemovalListener, + // so the entry is not decremented for the replaced value (hence we + // don't need to increment ram bytes for the entry either). + recordRamBytes(key, null, val); + } return old; } diff --git a/solr/core/src/test/org/apache/solr/search/TestCaffeineCache.java b/solr/core/src/test/org/apache/solr/search/TestCaffeineCache.java index 87ff29d5e6a..b4c69600fbd 100644 --- a/solr/core/src/test/org/apache/solr/search/TestCaffeineCache.java +++ b/solr/core/src/test/org/apache/solr/search/TestCaffeineCache.java @@ -308,7 +308,7 @@ public void testRamBytesSync() throws IOException { cache.put(0, "test"); long nonEmptySize = cache.ramBytesUsed(); - cache.put(0, "test"); + cache.put(0, random().nextBoolean() ? "test" : "rest"); assertEquals(nonEmptySize, cache.ramBytesUsed()); cache.remove(0); @@ -341,7 +341,7 @@ public void testRamBytesAsync() throws IOException { cache.put(0, "test"); long nonEmptySize = cache.ramBytesUsed(); - cache.put(0, "test"); + cache.put(0, random().nextBoolean() ? "test" : "rest"); assertEquals(nonEmptySize, cache.ramBytesUsed()); cache.remove(0);