diff --git a/.lgtm.yml b/.lgtm.yml new file mode 100644 index 0000000000..eb5f4c9b7a --- /dev/null +++ b/.lgtm.yml @@ -0,0 +1,4 @@ +extraction: + java: + index: + java_version: 11 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 26a79dfee4..2f9972fecd 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 @@ -299,13 +299,13 @@ public static CacheStats empty() { @CheckReturnValue public CacheStats minus(CacheStats other) { return CacheStats.of( - Math.max(0L, saturatedSubtract(hitCount, other.hitCount)), - Math.max(0L, saturatedSubtract(missCount, other.missCount)), - Math.max(0L, saturatedSubtract(loadSuccessCount, other.loadSuccessCount)), - Math.max(0L, saturatedSubtract(loadFailureCount, other.loadFailureCount)), - Math.max(0L, saturatedSubtract(totalLoadTime, other.totalLoadTime)), - Math.max(0L, saturatedSubtract(evictionCount, other.evictionCount)), - Math.max(0L, saturatedSubtract(evictionWeight, other.evictionWeight))); + Math.max(0L, hitCount - other.hitCount), + Math.max(0L, missCount - other.missCount), + Math.max(0L, loadSuccessCount - other.loadSuccessCount), + Math.max(0L, loadFailureCount - other.loadFailureCount), + Math.max(0L, totalLoadTime - other.totalLoadTime), + Math.max(0L, evictionCount - other.evictionCount), + Math.max(0L, evictionWeight - other.evictionWeight)); } /** @@ -331,22 +331,6 @@ public CacheStats plus(CacheStats other) { saturatedAdd(evictionWeight, other.evictionWeight)); } - /** - * Returns the difference of {@code a} and {@code b} unless it would overflow or underflow in - * which case {@code Long.MAX_VALUE} or {@code Long.MIN_VALUE} is returned, respectively. - */ - @SuppressWarnings("ShortCircuitBoolean") - private static long saturatedSubtract(long a, long b) { - long naiveDifference = a - b; - if (((a ^ b) >= 0) | ((a ^ naiveDifference) >= 0)) { - // If a and b have the same signs or a has the same sign as the result then there was no - // overflow, return. - return naiveDifference; - } - // we did over/under flow - return Long.MAX_VALUE + ((naiveDifference >>> (Long.SIZE - 1)) ^ 1); - } - /** * Returns the sum of {@code a} and {@code b} unless it would overflow or underflow in which case * {@code Long.MAX_VALUE} or {@code Long.MIN_VALUE} is returned, respectively. 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 b6ae29ba01..6188622594 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 @@ -94,6 +94,13 @@ public void overflow() { Long.MAX_VALUE, Long.MAX_VALUE); } + @Test + public void underflow() { + var max = CacheStats.of(Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE, + Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE); + assertThat(CacheStats.empty().minus(max)).isEqualTo(CacheStats.empty()); + } + private static void checkStats(CacheStats stats, long requestCount, long hitCount, double hitRate, long missCount, double missRate, long loadSuccessCount, long loadFailureCount, double loadFailureRate, long loadCount, long totalLoadTime, diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 261c5de9fb..51ca0428f0 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -27,7 +27,7 @@ ext { versions = [ akka: '2.6.19', cache2k: '2.6.1.Final', - checkerFramework: '3.21.3', + checkerFramework: '3.21.4', coherence: '20.06', commonsCompress: '1.21', commonsLang3: '3.12.0', @@ -49,7 +49,7 @@ ext { javapoet: '1.13.0', jcache: '1.1.1', jfreechart: '1.5.3', - jmh: '1.34', + jmh: '1.35', joor: '0.9.14', jsr330: '1', nullaway: '0.9.6', @@ -76,7 +76,7 @@ ext { lincheck: '2.14.1', mockito: '4.4.0', paxExam: '4.13.5', - slf4jTest: '2.6.0', + slf4jTest: '2.6.1', testng: '7.5', truth: '1.1.3', felix: '7.0.3', @@ -88,7 +88,7 @@ ext { bnd: '6.2.0', checkstyle: '10.1', coveralls: '2.12.0', - dependencyCheck: '7.0.1', + dependencyCheck: '7.0.3', errorprone: '2.0.2', findsecbugs: '1.11.0', jacoco: '0.8.7', @@ -173,6 +173,7 @@ ext { jcacheGuice: "org.jsr107.ri:cache-annotations-ri-guice:${versions.jcache}", jcacheTck: "javax.cache:cache-tests:${testVersions.jcacheTck}", jcacheTckTests: "javax.cache:cache-tests:${testVersions.jcacheTck}:tests", + jcacheTckTestSources: "javax.cache:cache-tests:${testVersions.jcacheTck}:test-sources", jctools: "org.jctools:jctools-core:${testVersions.jctools}", junit: "junit:junit:${testVersions.junit}", lincheck: "org.jetbrains.kotlinx:lincheck-jvm:${testVersions.lincheck}", diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 911403da5b..19251bf7a9 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,4 +1,4 @@ -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/jcache/build.gradle b/jcache/build.gradle index 5e626acabe..0ea04753da 100644 --- a/jcache/build.gradle +++ b/jcache/build.gradle @@ -1,7 +1,12 @@ /** * JCache compatibility adapter. */ +import org.gradle.plugins.ide.eclipse.model.Library + +apply plugin: 'eclipse' + configurations { + tckSources tck doc } @@ -27,6 +32,9 @@ dependencies { tck dependencies.create(testLibraries.jcacheTckTests) { transitive = false } + tckSources dependencies.create(testLibraries.jcacheTckTestSources) { + transitive = false + } doc "${libraries.jcache}:javadoc" } @@ -97,6 +105,11 @@ def testCompatibilityKit = tasks.register('testCompatibilityKit', Test) { systemProperty 'javax.management.builder.initial', "${pkg}.management.JCacheMBeanServerBuilder" } +eclipse.classpath.file.whenMerged { + def tests = entries.find { (it instanceof Library) && (it.path ==~ /.*cache-tests.*-tests.jar/) } + tests?.sourcePath = fileReference(file(configurations.tckSources.asPath)) +} + def osgiTest = tasks.register('osgiTest', Test) { group = 'Build' description = 'Isolated OSGi tests' diff --git a/jcache/src/main/java/com/github/benmanes/caffeine/jcache/expiry/JCacheExpiryPolicy.java b/jcache/src/main/java/com/github/benmanes/caffeine/jcache/expiry/JCacheExpiryPolicy.java index ac3bc5a18b..1e41652ac2 100644 --- a/jcache/src/main/java/com/github/benmanes/caffeine/jcache/expiry/JCacheExpiryPolicy.java +++ b/jcache/src/main/java/com/github/benmanes/caffeine/jcache/expiry/JCacheExpiryPolicy.java @@ -30,6 +30,7 @@ * * @author ben.manes@gmail.com (Ben Manes) */ +@SuppressWarnings("HashCodeToString") public final class JCacheExpiryPolicy implements ExpiryPolicy, Serializable { private static final long serialVersionUID = 1L; @@ -76,10 +77,4 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(creation, update, access); } - - @Override - public String toString() { - return String.format("%s{creation=%s, update=%s, access=%s}", - getClass().getSimpleName(), creation, update, access); - } } diff --git a/settings.gradle b/settings.gradle index 2662f0efc6..adb297e7bf 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,5 @@ plugins { - id 'com.gradle.enterprise' version '3.7.1' + id 'com.gradle.enterprise' version '3.9' } gradleEnterprise.buildScan {