diff --git a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/stats/CacheStats.java b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/stats/CacheStats.java index cac89ac5ca..48162fbbf2 100644 --- a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/stats/CacheStats.java +++ b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/stats/CacheStats.java @@ -53,12 +53,16 @@ * A lookup is specifically defined as an invocation of one of the methods * {@link LoadingCache#get(Object)}, {@link Cache#get(Object, java.util.function.Function)}, or * {@link LoadingCache#getAll(Iterable)}. + *

+ * This is a value-based class; use of identity-sensitive operations (including reference + * equality ({@code ==}), identity hash code, or synchronization) on instances of {@code CacheStats} + * may have unpredictable results and should be avoided. * * @author ben.manes@gmail.com (Ben Manes) */ @Immutable public final class CacheStats { - private static final CacheStats EMPTY_STATS = new CacheStats(0, 0, 0, 0, 0, 0, 0); + private static final CacheStats EMPTY_STATS = CacheStats.of(0L, 0L, 0L, 0L, 0L, 0L, 0L); private final long hitCount; private final long missCount; @@ -100,6 +104,7 @@ public CacheStats(@NonNegative long hitCount, @NonNegative long missCount, * @param evictionCount the number of entries evicted from the cache * @param evictionWeight the sum of weights of entries evicted from the cache */ + @Deprecated public CacheStats(@NonNegative long hitCount, @NonNegative long missCount, @NonNegative long loadSuccessCount, @NonNegative long loadFailureCount, @NonNegative long totalLoadTime, @NonNegative long evictionCount, @@ -117,6 +122,27 @@ public CacheStats(@NonNegative long hitCount, @NonNegative long missCount, this.evictionWeight = evictionWeight; } + /** + * Returns a {@code CacheStats} representing the specified statistics. + * + * @param hitCount the number of cache hits + * @param missCount the number of cache misses + * @param loadSuccessCount the number of successful cache loads + * @param loadFailureCount the number of failed cache loads + * @param totalLoadTime the total load time (success and failure) + * @param evictionCount the number of entries evicted from the cache + * @param evictionWeight the sum of weights of entries evicted from the cache + */ + public static CacheStats of(@NonNegative long hitCount, @NonNegative long missCount, + @NonNegative long loadSuccessCount, @NonNegative long loadFailureCount, + @NonNegative long totalLoadTime, @NonNegative long evictionCount, + @NonNegative long evictionWeight) { + // Many parameters of the same type in a row is a bad thing, but this class is not constructed + // by end users and is too fine-grained for a builder. + return new CacheStats(hitCount, missCount, loadSuccessCount, + loadFailureCount, totalLoadTime, evictionCount, evictionWeight); + } + /** * Returns a statistics instance where no cache events have been recorded. * @@ -317,7 +343,7 @@ public long evictionWeight() { */ @NonNull public CacheStats minus(@NonNull CacheStats other) { - return new CacheStats( + return CacheStats.of( Math.max(0L, saturatedSubtract(hitCount, other.hitCount)), Math.max(0L, saturatedSubtract(missCount, other.missCount)), Math.max(0L, saturatedSubtract(loadSuccessCount, other.loadSuccessCount)), @@ -340,7 +366,7 @@ public CacheStats minus(@NonNull CacheStats other) { */ @NonNull public CacheStats plus(@NonNull CacheStats other) { - return new CacheStats( + return CacheStats.of( saturatedAdd(hitCount, other.hitCount), saturatedAdd(missCount, other.missCount), saturatedAdd(loadSuccessCount, other.loadSuccessCount), diff --git a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/stats/ConcurrentStatsCounter.java b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/stats/ConcurrentStatsCounter.java index 4069a750bb..d61be562c5 100644 --- a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/stats/ConcurrentStatsCounter.java +++ b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/stats/ConcurrentStatsCounter.java @@ -92,7 +92,7 @@ public void recordEviction(int weight, RemovalCause cause) { @Override public CacheStats snapshot() { - return new CacheStats( + return CacheStats.of( negativeToMaxValue(hitCount.sum()), negativeToMaxValue(missCount.sum()), negativeToMaxValue(loadSuccessCount.sum()), diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CacheTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CacheTest.java index eb1d4939b0..cb63aff7d5 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CacheTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CacheTest.java @@ -852,9 +852,9 @@ public void serialize(Cache cache, CacheContext context) { @Test(dataProvider = "caches") public void stats(Cache cache, CacheContext context) { CacheStats stats = cache.stats() - .plus(new CacheStats(1, 2, 3, 4, 5, 6, 7) - .minus(new CacheStats(6, 5, 4, 3, 2, 1, 0))); - assertThat(stats, is(new CacheStats(0, 0, 0, 1, 3, 5, 7))); + .plus(CacheStats.of(1, 2, 3, 4, 5, 6, 7) + .minus(CacheStats.of(6, 5, 4, 3, 2, 1, 0))); + assertThat(stats, is(CacheStats.of(0, 0, 0, 1, 3, 5, 7))); assertThat(cache.policy().isRecordingStats(), is(context.isRecordingStats())); } diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/CacheStatsTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/CacheStatsTest.java index 3489fe467b..3faec84eb6 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/CacheStatsTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/CacheStatsTest.java @@ -32,13 +32,13 @@ public final class CacheStatsTest { @Test(dataProvider = "badArgs", expectedExceptions = IllegalArgumentException.class) public void invalid(int hitCount, int missCount, int loadSuccessCount, int loadFailureCount, int totalLoadTime, int evictionCount, int evictionWeight) { - new CacheStats(hitCount, missCount, loadSuccessCount, + CacheStats.of(hitCount, missCount, loadSuccessCount, loadFailureCount, totalLoadTime, evictionCount, evictionWeight); } @Test public void empty() { - CacheStats stats = new CacheStats(0, 0, 0, 0, 0, 0, 0); + CacheStats stats = CacheStats.of(0, 0, 0, 0, 0, 0, 0); checkStats(stats, 0, 0, 1.0, 0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0); assertThat(stats, is(equalTo(CacheStats.empty()))); @@ -51,7 +51,7 @@ public void empty() { @Test public void populated() { - CacheStats stats = new CacheStats(11, 13, 17, 19, 23, 27, 54); + CacheStats stats = CacheStats.of(11, 13, 17, 19, 23, 27, 54); checkStats(stats, 24, 11, 11.0/24, 13, 13.0/24, 17, 19, 19.0/36, 17 + 19, 23, 23.0/(17 + 19), 27, 54); @@ -60,7 +60,7 @@ public void populated() { assertThat(stats.hashCode(), is(not(CacheStats.empty().hashCode()))); assertThat(stats, hasToString(not(CacheStats.empty().toString()))); - CacheStats expected = new CacheStats(11, 13, 17, 19, 23, 27, 54); + CacheStats expected = CacheStats.of(11, 13, 17, 19, 23, 27, 54); assertThat(stats, is(equalTo(expected))); assertThat(stats.hashCode(), is(expected.hashCode())); assertThat(stats, hasToString(expected.toString())); @@ -68,8 +68,8 @@ public void populated() { @Test public void minus() { - CacheStats one = new CacheStats(11, 13, 17, 19, 23, 27, 54); - CacheStats two = new CacheStats(53, 47, 43, 41, 37, 31, 62); + CacheStats one = CacheStats.of(11, 13, 17, 19, 23, 27, 54); + CacheStats two = CacheStats.of(53, 47, 43, 41, 37, 31, 62); CacheStats diff = two.minus(one); checkStats(diff, 76, 42, 42.0 / 76, 34, 34.0 / 76, @@ -79,8 +79,8 @@ public void minus() { @Test public void plus() { - CacheStats one = new CacheStats(11, 13, 15, 13, 11, 9, 18); - CacheStats two = new CacheStats(53, 47, 41, 39, 37, 35, 70); + CacheStats one = CacheStats.of(11, 13, 15, 13, 11, 9, 18); + CacheStats two = CacheStats.of(53, 47, 41, 39, 37, 35, 70); CacheStats sum = two.plus(one); checkStats(sum, 124, 64, 64.0 / 124, 60, 60.0 / 124, @@ -91,7 +91,7 @@ public void plus() { @Test public void overflow() { - CacheStats max = new CacheStats(Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE, + CacheStats max = CacheStats.of(Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE); checkStats(max.plus(max), Long.MAX_VALUE, Long.MAX_VALUE, 1.0, Long.MAX_VALUE, 1.0, Long.MAX_VALUE, Long.MAX_VALUE, 1.0, Long.MAX_VALUE, Long.MAX_VALUE, 1.0, diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/StatsCounterTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/StatsCounterTest.java index 91313ae5e3..e646063e20 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/StatsCounterTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/stats/StatsCounterTest.java @@ -46,8 +46,8 @@ public void disabled() { counter.recordEviction(1, RemovalCause.SIZE); counter.recordLoadSuccess(1); counter.recordLoadFailure(1); - assertThat(counter.snapshot(), is(new CacheStats(0, 0, 0, 0, 0, 0, 0))); - assertThat(counter.toString(), is(new CacheStats(0, 0, 0, 0, 0, 0, 0).toString())); + assertThat(counter.snapshot(), is(CacheStats.of(0, 0, 0, 0, 0, 0, 0))); + assertThat(counter.toString(), is(CacheStats.of(0, 0, 0, 0, 0, 0, 0).toString())); for (DisabledStatsCounter type : DisabledStatsCounter.values()) { assertThat(DisabledStatsCounter.valueOf(type.name()), is(counter)); @@ -64,13 +64,13 @@ public void enabled() { counter.recordEviction(1, RemovalCause.SIZE); counter.recordLoadSuccess(1); counter.recordLoadFailure(1); - CacheStats expected = new CacheStats(1, 1, 1, 1, 2, 3, 11); + CacheStats expected = CacheStats.of(1, 1, 1, 1, 2, 3, 11); assertThat(counter.snapshot(), is(expected)); assertThat(counter.toString(), is(expected.toString())); assertThat(counter.snapshot().toString(), is(expected.toString())); counter.incrementBy(counter); - assertThat(counter.snapshot(), is(new CacheStats(2, 2, 2, 2, 4, 6, 22))); + assertThat(counter.snapshot(), is(CacheStats.of(2, 2, 2, 2, 4, 6, 22))); } @Test @@ -84,7 +84,7 @@ public void concurrent() { counter.recordLoadSuccess(1); counter.recordLoadFailure(1); }); - assertThat(counter.snapshot(), is(new CacheStats(5, 5, 5, 5, 10, 10, 50))); + assertThat(counter.snapshot(), is(CacheStats.of(5, 5, 5, 5, 10, 10, 50))); } @Test @@ -97,7 +97,7 @@ public void guarded() { counter.recordEviction(1, RemovalCause.SIZE); counter.recordLoadSuccess(1); counter.recordLoadFailure(1); - CacheStats expected = new CacheStats(1, 1, 1, 1, 2, 3, 11); + CacheStats expected = CacheStats.of(1, 1, 1, 1, 2, 3, 11); assertThat(counter.snapshot(), is(expected)); assertThat(counter.toString(), is(expected.toString())); assertThat(counter.snapshot().toString(), is(expected.toString())); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/GuavaCacheFromContext.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/GuavaCacheFromContext.java index 245e55d414..176b9267a6 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/GuavaCacheFromContext.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/testing/GuavaCacheFromContext.java @@ -258,7 +258,7 @@ public long estimatedSize() { @Override public CacheStats stats() { com.google.common.cache.CacheStats stats = statsCounter.snapshot().plus(cache.stats()); - return new CacheStats(stats.hitCount(), stats.missCount(), stats.loadSuccessCount(), + return CacheStats.of(stats.hitCount(), stats.missCount(), stats.loadSuccessCount(), stats.loadExceptionCount(), stats.totalLoadTime(), stats.evictionCount(), 0L); } diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index c48f47a1e9..67ea9b66e2 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -57,7 +57,7 @@ ext { nullaway: '0.7.9', ohc: '0.6.1', osgiComponentAnnotations: '1.4.0', - picocli: '4.6.0', + picocli: '4.6.1', slf4j: '1.7.30', tcache: '2.0.1', stream: '2.9.8', diff --git a/guava/src/test/java/com/google/common/cache/AbstractCacheTest.java b/guava/src/test/java/com/google/common/cache/AbstractCacheTest.java index 5224509c18..01765e2e54 100644 --- a/guava/src/test/java/com/google/common/cache/AbstractCacheTest.java +++ b/guava/src/test/java/com/google/common/cache/AbstractCacheTest.java @@ -128,6 +128,6 @@ public void testSimpleStatsIncrementBy() { } counter1.incrementBy(counter2); - assertEquals(new CacheStats(38, 60, 44, 54, totalLoadTime, 66, 66), counter1.snapshot()); + assertEquals(CacheStats.of(38, 60, 44, 54, totalLoadTime, 66, 66), counter1.snapshot()); } } diff --git a/guava/src/test/java/com/google/common/cache/CacheStatsTest.java b/guava/src/test/java/com/google/common/cache/CacheStatsTest.java index 49132bc034..d09655f847 100644 --- a/guava/src/test/java/com/google/common/cache/CacheStatsTest.java +++ b/guava/src/test/java/com/google/common/cache/CacheStatsTest.java @@ -29,7 +29,7 @@ public class CacheStatsTest extends TestCase { public void testEmpty() { - CacheStats stats = new CacheStats(0, 0, 0, 0, 0, 0, 0); + CacheStats stats = CacheStats.of(0, 0, 0, 0, 0, 0, 0); assertEquals(0, stats.requestCount()); assertEquals(0, stats.hitCount()); assertEquals(1.0, stats.hitRate()); @@ -45,7 +45,7 @@ public void testEmpty() { } public void testSingle() { - CacheStats stats = new CacheStats(11, 13, 17, 19, 23, 27, 54); + CacheStats stats = CacheStats.of(11, 13, 17, 19, 23, 27, 54); assertEquals(24, stats.requestCount()); assertEquals(11, stats.hitCount()); assertEquals(11.0/24, stats.hitRate()); @@ -62,8 +62,8 @@ public void testSingle() { } public void testMinus() { - CacheStats one = new CacheStats(11, 13, 17, 19, 23, 27, 54); - CacheStats two = new CacheStats(53, 47, 43, 41, 37, 31, 62); + CacheStats one = CacheStats.of(11, 13, 17, 19, 23, 27, 54); + CacheStats two = CacheStats.of(53, 47, 43, 41, 37, 31, 62); CacheStats diff = two.minus(one); assertEquals(76, diff.requestCount()); @@ -80,12 +80,12 @@ public void testMinus() { assertEquals(4, diff.evictionCount()); assertEquals(8, diff.evictionWeight()); - assertEquals(new CacheStats(0, 0, 0, 0, 0, 0, 0), one.minus(two)); + assertEquals(CacheStats.of(0, 0, 0, 0, 0, 0, 0), one.minus(two)); } public void testPlus() { - CacheStats one = new CacheStats(11, 13, 15, 13, 11, 9, 18); - CacheStats two = new CacheStats(53, 47, 41, 39, 37, 35, 70); + CacheStats one = CacheStats.of(11, 13, 15, 13, 11, 9, 18); + CacheStats two = CacheStats.of(53, 47, 41, 39, 37, 35, 70); CacheStats sum = two.plus(one); assertEquals(124, sum.requestCount()); @@ -107,7 +107,7 @@ public void testPlus() { public void testPlusLarge() { CacheStats maxCacheStats = - new CacheStats( + CacheStats.of( Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE, @@ -115,7 +115,7 @@ public void testPlusLarge() { Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE); - CacheStats smallCacheStats = new CacheStats(1, 1, 1, 1, 1, 1, 1); + CacheStats smallCacheStats = CacheStats.of(1, 1, 1, 1, 1, 1, 1); CacheStats sum = smallCacheStats.plus(maxCacheStats); assertEquals(Long.MAX_VALUE, sum.requestCount());