diff --git a/.travis.yml b/.travis.yml index 4c34b8c33e..a69744b65d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,6 +27,10 @@ addons: apt: packages: - oracle-java8-installer + sonarcloud: + organization: caffeine + token: + secure: "D40GIdgUfGx75Yso8Zjo/E0dIsW9KDDyId5wbBNuozMkxJcS2qOIK1+Ia3GPHKSvkeSQJ/1wVyl3TGJunGZB/dLoZvrqtKwaLCOa/9TZA1+Uc80W88uvaZ5yhoZP4vCQV3ka+2eRBBYUzYUptK0qdpJxWRyAmPFvOqtnHmDYgb4=" before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock @@ -34,5 +38,6 @@ before_cache: cache: directories: - $HOME/.m2 + - $HOME/.sonar/cache - $HOME/.gradle/caches/ - $HOME/.gradle/wrapper/ diff --git a/caffeine/build.gradle b/caffeine/build.gradle index d31211cca9..d0a90dd309 100644 --- a/caffeine/build.gradle +++ b/caffeine/build.gradle @@ -66,6 +66,12 @@ jar.manifest { 'com.github.benmanes.caffeine.cache.stats' } +sonarqube { + properties { + property "sonar.exclusions", '**/NodeFactory.java, **/LocalCacheFactory.java' + } +} + task generateLocalCaches(type: JavaExec) { main = 'com.github.benmanes.caffeine.cache.LocalCacheFactoryGenerator' classpath = sourceSets.javaPoet.runtimeClasspath diff --git a/caffeine/src/main/java/com/github/benmanes/caffeine/base/UnsafeAccess.java b/caffeine/src/main/java/com/github/benmanes/caffeine/base/UnsafeAccess.java index d55c9429ee..020d398576 100644 --- a/caffeine/src/main/java/com/github/benmanes/caffeine/base/UnsafeAccess.java +++ b/caffeine/src/main/java/com/github/benmanes/caffeine/base/UnsafeAccess.java @@ -61,8 +61,7 @@ public static long objectFieldOffset(Class clazz, String fieldName) { } static Unsafe load(String openJdk, String android) throws NoSuchMethodException, - SecurityException, InstantiationException, IllegalAccessException, - IllegalArgumentException, InvocationTargetException { + InstantiationException, IllegalAccessException, InvocationTargetException { Field field; try { // try OpenJDK field name diff --git a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/Async.java b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/Async.java index d926344f7a..a498641820 100644 --- a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/Async.java +++ b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/Async.java @@ -77,9 +77,7 @@ static final class AsyncRemovalListener @Override @SuppressWarnings("FutureReturnValueIgnored") public void onRemoval(K key, @Nonnull CompletableFuture future, RemovalCause cause) { - future.thenAcceptAsync(value -> { - delegate.onRemoval(key, value, cause); - }, executor); + future.thenAcceptAsync(value -> delegate.onRemoval(key, value, cause), executor); } Object writeReplace() { diff --git a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedBuffer.java b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedBuffer.java index c3eb71e9dc..81f79085f7 100644 --- a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedBuffer.java +++ b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedBuffer.java @@ -124,13 +124,13 @@ public int writes() { final class BBHeader { @SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod") - static abstract class PadReadCounter { + abstract static class PadReadCounter { long p00, p01, p02, p03, p04, p05, p06, p07; long p10, p11, p12, p13, p14, p15, p16; } /** Enforces a memory layout to avoid false sharing by padding the read count. */ - static abstract class ReadCounterRef extends PadReadCounter { + abstract static class ReadCounterRef extends PadReadCounter { static final long READ_OFFSET = UnsafeAccess.objectFieldOffset(ReadCounterRef.class, "readCounter"); @@ -141,13 +141,13 @@ void lazySetReadCounter(long count) { } } - static abstract class PadWriteCounter extends ReadCounterRef { + abstract static class PadWriteCounter extends ReadCounterRef { long p20, p21, p22, p23, p24, p25, p26, p27; long p30, p31, p32, p33, p34, p35, p36; } /** Enforces a memory layout to avoid false sharing by padding the write count. */ - static abstract class ReadAndWriteCounterRef extends PadWriteCounter { + abstract static class ReadAndWriteCounterRef extends PadWriteCounter { static final long WRITE_OFFSET = UnsafeAccess.objectFieldOffset(ReadAndWriteCounterRef.class, "writeCounter"); diff --git a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedLocalCache.java b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedLocalCache.java index aaa8af7d35..81e1110299 100644 --- a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedLocalCache.java +++ b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedLocalCache.java @@ -997,9 +997,8 @@ void setAccessTime(Node node, long now) { * Performs the post-processing work required after a write. * * @param task the pending operation to be applied - * @param now the current time, in nanoseconds */ - void afterWrite(Runnable task, long now) { + void afterWrite(Runnable task) { if (buffersWrites()) { for (int i = 0; i < WRITE_BUFFER_RETRIES; i++) { if (writeBuffer().offer(task)) { @@ -1649,13 +1648,13 @@ V put(K key, V value, boolean notifyWriter, boolean onlyIfAbsent) { return computed; }); if (prior == node) { - afterWrite(new AddTask(node, newWeight), now); + afterWrite(new AddTask(node, newWeight)); return null; } } else { prior = data.putIfAbsent(node.getKeyReference(), node); if (prior == null) { - afterWrite(new AddTask(node, newWeight), now); + afterWrite(new AddTask(node, newWeight)); return null; } } @@ -1714,9 +1713,9 @@ V put(K key, V value, boolean notifyWriter, boolean onlyIfAbsent) { int weightedDifference = mayUpdate ? (newWeight - oldWeight) : 0; if ((oldValue == null) || (weightedDifference != 0) || expired) { - afterWrite(new UpdateTask(prior, weightedDifference), now); + afterWrite(new UpdateTask(prior, weightedDifference)); } else if (!onlyIfAbsent && expiresAfterWrite() && withinTolerance) { - afterWrite(new UpdateTask(prior, weightedDifference), now); + afterWrite(new UpdateTask(prior, weightedDifference)); } else { if (mayUpdate) { setWriteTime(prior, now); @@ -1769,7 +1768,7 @@ V removeNoWriter(Object key) { K castKey = (K) key; notifyRemoval(castKey, oldValue, cause); } - afterWrite(new RemovalTask(node), 0L); + afterWrite(new RemovalTask(node)); return (cause == RemovalCause.EXPLICIT) ? oldValue : null; } @@ -1807,7 +1806,7 @@ V removeWithWriter(Object key) { }); if (cause[0] != null) { - afterWrite(new RemovalTask(node[0]), now); + afterWrite(new RemovalTask(node[0])); if (hasRemovalListener()) { notifyRemoval(castKey, oldValue[0], cause[0]); } @@ -1823,7 +1822,7 @@ public boolean remove(Object key, Object value) { } @SuppressWarnings({"unchecked", "rawtypes"}) - Node removed[] = new Node[1]; + Node[] removed = new Node[1]; @SuppressWarnings("unchecked") K[] oldKey = (K[]) new Object[1]; @SuppressWarnings("unchecked") @@ -1856,7 +1855,7 @@ public boolean remove(Object key, Object value) { } else if (hasRemovalListener()) { notifyRemoval(oldKey[0], oldValue[0], cause[0]); } - afterWrite(new RemovalTask(removed[0]), now); + afterWrite(new RemovalTask(removed[0])); return (cause[0] == RemovalCause.EXPLICIT); } @@ -1902,7 +1901,7 @@ public V replace(K key, V value) { int weightedDifference = (weight - oldWeight[0]); if (expiresAfterWrite() || (weightedDifference != 0)) { - afterWrite(new UpdateTask(node, weightedDifference), now); + afterWrite(new UpdateTask(node, weightedDifference)); } else { afterRead(node, now, /* recordHit */ false); } @@ -1958,7 +1957,7 @@ public boolean replace(K key, V oldValue, V newValue) { int weightedDifference = (weight - oldWeight[0]); if (expiresAfterWrite() || (weightedDifference != 0)) { - afterWrite(new UpdateTask(node, weightedDifference), now); + afterWrite(new UpdateTask(node, weightedDifference)); } else { afterRead(node, now, /* recordHit */ false); } @@ -2076,7 +2075,7 @@ V doComputeIfAbsent(K key, Object keyRef, if (node == null) { if (removed[0] != null) { - afterWrite(new RemovalTask(removed[0]), now); + afterWrite(new RemovalTask(removed[0])); } return null; } @@ -2096,10 +2095,10 @@ V doComputeIfAbsent(K key, Object keyRef, return oldValue[0]; } if ((oldValue[0] == null) && (cause[0] == null)) { - afterWrite(new AddTask(node, weight[1]), now); + afterWrite(new AddTask(node, weight[1])); } else { int weightedDifference = (weight[1] - weight[0]); - afterWrite(new UpdateTask(node, weightedDifference), now); + afterWrite(new UpdateTask(node, weightedDifference)); } return newValue[0]; @@ -2257,15 +2256,15 @@ V remap(K key, Object keyRef, BiFunction rema } if (removed[0] != null) { - afterWrite(new RemovalTask(removed[0]), now); + afterWrite(new RemovalTask(removed[0])); } else if (node == null) { // absent and not computable } else if ((oldValue[0] == null) && (cause[0] == null)) { - afterWrite(new AddTask(node, weight[1]), now); + afterWrite(new AddTask(node, weight[1])); } else { int weightedDifference = weight[1] - weight[0]; if (expiresAfterWrite() || (weightedDifference != 0)) { - afterWrite(new UpdateTask(node, weightedDifference), now); + afterWrite(new UpdateTask(node, weightedDifference)); } else { if (cause[0] == null) { if (!isComputingAsync(node)) { @@ -3420,13 +3419,13 @@ Object writeReplace() { /** The namespace for field padding through inheritance. */ final class BLCHeader { - static abstract class PadDrainStatus extends AbstractMap { + abstract static class PadDrainStatus extends AbstractMap { long p00, p01, p02, p03, p04, p05, p06, p07; long p10, p11, p12, p13, p14, p15, p16; } /** Enforces a memory layout to avoid false sharing by padding the drain status. */ - static abstract class DrainStatusRef extends PadDrainStatus { + abstract static class DrainStatusRef extends PadDrainStatus { static final long DRAIN_STATUS_OFFSET = UnsafeAccess.objectFieldOffset(DrainStatusRef.class, "drainStatus"); diff --git a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/Caffeine.java b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/Caffeine.java index 1f7330e91d..05e31e2edb 100644 --- a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/Caffeine.java +++ b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/Caffeine.java @@ -807,7 +807,7 @@ boolean isRecordingStats() { } @Nonnull - Supplier getStatsCounterSupplier() { + Supplier getStatsCounterSupplier() { return (statsCounterSupplier == null) ? StatsCounter::disabledStatsCounter : statsCounterSupplier; diff --git a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/UnboundedLocalCache.java b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/UnboundedLocalCache.java index d45e4e5a09..ee91564fab 100644 --- a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/UnboundedLocalCache.java +++ b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/UnboundedLocalCache.java @@ -369,7 +369,7 @@ public V put(K key, V value, boolean notifyWriter) { // ensures that the removal notification is processed after the removal has completed @SuppressWarnings({"unchecked", "rawtypes"}) - V oldValue[] = (V[]) new Object[1]; + V[] oldValue = (V[]) new Object[1]; if ((writer == CacheWriter.disabledWriter()) || !notifyWriter) { oldValue[0] = data.put(key, value); } else { @@ -416,7 +416,7 @@ public V remove(Object key) { @SuppressWarnings("unchecked") K castKey = (K) key; @SuppressWarnings({"unchecked", "rawtypes"}) - V oldValue[] = (V[]) new Object[1]; + V[] oldValue = (V[]) new Object[1]; if (writer == CacheWriter.disabledWriter()) { oldValue[0] = data.remove(key); @@ -445,7 +445,7 @@ public boolean remove(Object key, Object value) { @SuppressWarnings("unchecked") K castKey = (K) key; @SuppressWarnings({"unchecked", "rawtypes"}) - V oldValue[] = (V[]) new Object[1]; + V[] oldValue = (V[]) new Object[1]; data.computeIfPresent(castKey, (k, v) -> { if (v.equals(value)) { @@ -468,7 +468,7 @@ public V replace(K key, V value) { requireNonNull(value); @SuppressWarnings({"unchecked", "rawtypes"}) - V oldValue[] = (V[]) new Object[1]; + V[] oldValue = (V[]) new Object[1]; data.computeIfPresent(key, (k, v) -> { if (value != v) { writer.write(key, value); @@ -489,7 +489,7 @@ public boolean replace(K key, V oldValue, V newValue) { requireNonNull(newValue); @SuppressWarnings({"unchecked", "rawtypes"}) - V prev[] = (V[]) new Object[1]; + V[] prev = (V[]) new Object[1]; data.computeIfPresent(key, (k, v) -> { if (v.equals(oldValue)) { if (newValue != v) { diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/BoundedLocalCacheTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/BoundedLocalCacheTest.java index f65bdb000e..2d84a4a848 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/BoundedLocalCacheTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/BoundedLocalCacheTest.java @@ -434,7 +434,7 @@ public void exceedsMaximumBufferSize_onWrite(Cache cache, Cach BoundedLocalCache localCache = asBoundedLocalCache(cache); boolean[] ran = new boolean[1]; - localCache.afterWrite(() -> ran[0] = true, 0); + localCache.afterWrite(() -> ran[0] = true); assertThat(ran[0], is(true)); assertThat(localCache.writeBuffer().size(), is(0)); @@ -480,7 +480,7 @@ public void afterWrite_drainFullWriteBuffer(Cache cache, Cache int[] triggered = { 0 }; Runnable triggerTask = () -> triggered[0] = 1 + expectedCount[0]; - localCache.afterWrite(triggerTask, 0L); + localCache.afterWrite(triggerTask); assertThat(processed[0], is(expectedCount[0])); assertThat(triggered[0], is(expectedCount[0] + 1)); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CaffeineSpecTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CaffeineSpecTest.java index 5556632031..5aa935e6b8 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CaffeineSpecTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/CaffeineSpecTest.java @@ -55,7 +55,8 @@ public final class CaffeineSpecTest { static final long UNSET_LONG = UNSET_INT; @Test(dataProvider = "caches") - @CacheSpec(population = Population.EMPTY, compute = Compute.SYNC, writer = Writer.DISABLED, + @CacheSpec(initialCapacity = {InitialCapacity.DEFAULT, InitialCapacity.FULL}, + population = Population.EMPTY, compute = Compute.SYNC, writer = Writer.DISABLED, removalListener = Listener.DEFAULT, implementation = Implementation.Caffeine) public void specifications(CacheContext context) { CaffeineSpec spec = toSpec(context); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/FastFlowBuffer.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/FastFlowBuffer.java index b309a96688..e0f8e6342e 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/FastFlowBuffer.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/FastFlowBuffer.java @@ -97,13 +97,13 @@ public int writes() { /** The namespace for field padding through inheritance. */ final class FastFlowHeader { - static abstract class PadReadCache extends ReadBuffer { + abstract static class PadReadCache extends ReadBuffer { long p00, p01, p02, p03, p04, p05, p06, p07; long p10, p11, p12, p13, p14, p15, p16, p17; } /** Enforces a memory layout to avoid false sharing by padding the read count. */ - static abstract class ReadCacheRef extends PadReadCache { + abstract static class ReadCacheRef extends PadReadCache { static final long READ_CACHE_OFFSET = UnsafeAccess.objectFieldOffset(ReadCacheRef.class, "readCache"); @@ -114,13 +114,13 @@ void lazySetReadCache(long count) { } } - static abstract class PadReadCounter extends ReadCacheRef { + abstract static class PadReadCounter extends ReadCacheRef { long p20, p21, p22, p23, p24, p25, p26, p27; long p30, p31, p32, p33, p34, p35, p36, p37; } /** Enforces a memory layout to avoid false sharing by padding the read count. */ - static abstract class ReadCounterRef extends PadReadCounter { + abstract static class ReadCounterRef extends PadReadCounter { static final long READ_OFFSET = UnsafeAccess.objectFieldOffset(ReadCounterRef.class, "readCounter"); @@ -131,13 +131,13 @@ void lazySetReadCounter(long count) { } } - static abstract class PadWriteCounter extends ReadCounterRef { + abstract static class PadWriteCounter extends ReadCounterRef { long p40, p41, p42, p43, p44, p45, p46, p47; long p50, p51, p52, p53, p54, p55, p56, p57; } /** Enforces a memory layout to avoid false sharing by padding the write count. */ - static abstract class ReadAndWriteCounterRef extends PadWriteCounter { + abstract static class ReadAndWriteCounterRef extends PadWriteCounter { static final long WRITE_OFFSET = UnsafeAccess.objectFieldOffset(ReadAndWriteCounterRef.class, "writeCounter"); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/ManyToOneBuffer.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/ManyToOneBuffer.java index 8129f406be..8f445e8915 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/ManyToOneBuffer.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/ManyToOneBuffer.java @@ -91,13 +91,13 @@ public int writes() { /** The namespace for field padding through inheritance. */ final class ManyToOneHeader { - static abstract class PadReadCounter extends ReadBuffer { + abstract static class PadReadCounter extends ReadBuffer { long p00, p01, p02, p03, p04, p05, p06, p07; long p10, p11, p12, p13, p14, p15, p16, p17; } /** Enforces a memory layout to avoid false sharing by padding the read count. */ - static abstract class ReadCounterRef extends PadReadCounter { + abstract static class ReadCounterRef extends PadReadCounter { static final long READ_OFFSET = UnsafeAccess.objectFieldOffset(ReadCounterRef.class, "readCounter"); @@ -108,13 +108,13 @@ void lazySetReadCounter(long count) { } } - static abstract class PadWriteCounter extends ReadCounterRef { + abstract static class PadWriteCounter extends ReadCounterRef { long p20, p21, p22, p23, p24, p25, p26, p27; long p30, p31, p32, p33, p34, p35, p36, p37; } /** Enforces a memory layout to avoid false sharing by padding the write count. */ - static abstract class ReadAndWriteCounterRef extends PadWriteCounter { + abstract static class ReadAndWriteCounterRef extends PadWriteCounter { static final long WRITE_OFFSET = UnsafeAccess.objectFieldOffset(ReadAndWriteCounterRef.class, "writeCounter"); diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/ManyToOneSpacedBuffer.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/ManyToOneSpacedBuffer.java index d8a4d3f222..0f2c0631c8 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/ManyToOneSpacedBuffer.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/buffer/ManyToOneSpacedBuffer.java @@ -95,13 +95,13 @@ public int writes() { /** The namespace for field padding through inheritance. */ final class ManyToOneSpacedHeader { - static abstract class PadReadCounter extends ReadBuffer { + abstract static class PadReadCounter extends ReadBuffer { long p00, p01, p02, p03, p04, p05, p06, p07; long p10, p11, p12, p13, p14, p15, p16, p17; } /** Enforces a memory layout to avoid false sharing by padding the read count. */ - static abstract class ReadCounterRef extends PadReadCounter { + abstract static class ReadCounterRef extends PadReadCounter { static final long READ_OFFSET = UnsafeAccess.objectFieldOffset(ReadCounterRef.class, "readCounter"); @@ -112,13 +112,13 @@ void lazySetReadCounter(long count) { } } - static abstract class PadWriteCounter extends ReadCounterRef { + abstract static class PadWriteCounter extends ReadCounterRef { long p20, p21, p22, p23, p24, p25, p26, p27; long p30, p31, p32, p33, p34, p35, p36, p37; } /** Enforces a memory layout to avoid false sharing by padding the write count. */ - static abstract class ReadAndWriteCounterRef extends PadWriteCounter { + abstract static class ReadAndWriteCounterRef extends PadWriteCounter { static final long WRITE_OFFSET = UnsafeAccess.objectFieldOffset(ReadAndWriteCounterRef.class, "writeCounter"); diff --git a/gradle/codeQuality.gradle b/gradle/codeQuality.gradle index 96d62a57c8..4b470596c3 100644 --- a/gradle/codeQuality.gradle +++ b/gradle/codeQuality.gradle @@ -3,6 +3,7 @@ */ apply plugin: 'org.kordamp.gradle.stats' apply plugin: 'com.github.spotbugs' +apply plugin: 'org.sonarqube' apply plugin: 'checkstyle' apply plugin: 'jacoco' apply plugin: 'java' @@ -57,6 +58,21 @@ jacocoTestReport { } } +task jacocoMerge(type: JacocoMerge) { + executionData tasks.withType(Test) + + doFirst { + executionData = files(executionData.findAll { it.exists() }) + } +} + +sonarqube { + properties { + property 'sonar.jacoco.reportPath', jacocoMerge.destinationFile + } +} +tasks.sonarqube.dependsOn(jacocoMerge) + tasks.withType(Test) { if (System.properties.containsKey('debug')) { jvmArgs '-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005' diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 31b5af99e5..216e60d1ae 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -55,7 +55,7 @@ ext { truth: '0.24', ] benchmarkVersions = [ - cache2k: '1.0.0.CR4', + cache2k: '1.0.0.Final', collision: '0.3.2', concurrentlinkedhashmap: '1.4.2', ehcache2: '2.10.4', @@ -87,6 +87,7 @@ ext { propdeps: '0.0.10.RELEASE', semanticVersioning: '1.1.0', shadow: '2.0.1', + sonarqube: '2.5', spotbugs: '1.0', stats: '0.2.0', versions: '0.15.0', @@ -188,6 +189,7 @@ ext { propdeps: "io.spring.gradle:propdeps-plugin:${pluginVersions.propdeps}", semanticVersioning: "io.ehdev:gradle-semantic-versioning:${pluginVersions.semanticVersioning}", shadow: "com.github.jengelman.gradle.plugins:shadow:${pluginVersions.shadow}", + sonarqube: "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:${pluginVersions.sonarqube}", spotbugs: "gradle.plugin.com.github.spotbugs:gradlePlugin:${pluginVersions.spotbugs}", stats: "org.kordamp.gradle:stats-gradle-plugin:${pluginVersions.stats}", versions: "com.github.ben-manes:gradle-versions-plugin:${pluginVersions.versions}", diff --git a/guava/src/main/java/com/github/benmanes/caffeine/guava/CaffeinatedGuavaCache.java b/guava/src/main/java/com/github/benmanes/caffeine/guava/CaffeinatedGuavaCache.java index b3013177db..472daf9f85 100644 --- a/guava/src/main/java/com/github/benmanes/caffeine/guava/CaffeinatedGuavaCache.java +++ b/guava/src/main/java/com/github/benmanes/caffeine/guava/CaffeinatedGuavaCache.java @@ -48,7 +48,7 @@ class CaffeinatedGuavaCache implements Cache, Serializable { static final long serialVersionUID = 1L; - final com.github.benmanes.caffeine.cache.Cache cache; + private final com.github.benmanes.caffeine.cache.Cache cache; CaffeinatedGuavaCache(com.github.benmanes.caffeine.cache.Cache cache) { this.cache = requireNonNull(cache); diff --git a/guava/src/main/java/com/github/benmanes/caffeine/guava/CaffeinatedGuavaLoadingCache.java b/guava/src/main/java/com/github/benmanes/caffeine/guava/CaffeinatedGuavaLoadingCache.java index b546305154..04f5734910 100644 --- a/guava/src/main/java/com/github/benmanes/caffeine/guava/CaffeinatedGuavaLoadingCache.java +++ b/guava/src/main/java/com/github/benmanes/caffeine/guava/CaffeinatedGuavaLoadingCache.java @@ -44,7 +44,7 @@ final class CaffeinatedGuavaLoadingCache extends CaffeinatedGuavaCache nullBulkLoad = ThreadLocal.withInitial(() -> Boolean.FALSE); static final long serialVersionUID = 1L; - final com.github.benmanes.caffeine.cache.LoadingCache cache; + private final com.github.benmanes.caffeine.cache.LoadingCache cache; CaffeinatedGuavaLoadingCache(com.github.benmanes.caffeine.cache.LoadingCache cache) { super(cache); diff --git a/guava/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeTests.java b/guava/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeTests.java index 7a12521e2c..6588de957d 100644 --- a/guava/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeTests.java +++ b/guava/src/test/java/com/github/benmanes/caffeine/cache/LinkedDequeTests.java @@ -86,7 +86,7 @@ protected static Test suite(String name, Supplier> supp } /** See TestStringQueueGenerator */ - static abstract class TestLinkedValueGenerator implements TestQueueGenerator { + abstract static class TestLinkedValueGenerator implements TestQueueGenerator { @Override public SampleElements samples() { diff --git a/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheFactory.java b/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheFactory.java index d5e542c21f..bb13b7fc8c 100644 --- a/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheFactory.java +++ b/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheFactory.java @@ -128,7 +128,7 @@ private final class Builder { final Ticker ticker; final String cacheName; final Executor executor; - final ExpiryPolicy expiry; + final ExpiryPolicy expiryPolicy; final EventDispatcher dispatcher; final JCacheStatisticsMXBean statistics; final Caffeine caffeine; @@ -143,7 +143,7 @@ private final class Builder { this.caffeine = Caffeine.newBuilder(); this.statistics = new JCacheStatisticsMXBean(); this.ticker = config.getTickerFactory().create(); - this.expiry = config.getExpiryPolicyFactory().create(); + this.expiryPolicy = config.getExpiryPolicyFactory().create(); this.executor = USE_DIRECT_EXECUTOR ? Runnable::run : config.getExecutorFactory().create(); this.dispatcher = new EventDispatcher<>(executor); @@ -185,15 +185,15 @@ private boolean isReadThrough() { /** Creates a cache that does not read through on a cache miss. */ private CacheProxy newCacheProxy() { return new CacheProxy<>(cacheName, executor, cacheManager, config, caffeine.build(), - dispatcher, Optional.ofNullable(cacheLoader), expiry, ticker, statistics); + dispatcher, Optional.ofNullable(cacheLoader), expiryPolicy, ticker, statistics); } /** Creates a cache that reads through on a cache miss. */ private CacheProxy newLoadingCacheProxy() { JCacheLoaderAdapter adapter = new JCacheLoaderAdapter<>( - cacheLoader, dispatcher, expiry, ticker, statistics); + cacheLoader, dispatcher, expiryPolicy, ticker, statistics); CacheProxy cache = new LoadingCacheProxy<>(cacheName, executor, cacheManager, - config, caffeine.build(adapter), dispatcher, cacheLoader, expiry, ticker, statistics); + config, caffeine.build(adapter), dispatcher, cacheLoader, expiryPolicy, ticker, statistics); adapter.setCache(cache); return cache; } diff --git a/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheManagerImpl.java b/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheManagerImpl.java index 31548c47e4..7e56c4ca3d 100644 --- a/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheManagerImpl.java +++ b/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheManagerImpl.java @@ -86,8 +86,8 @@ public Properties getProperties() { } @Override - public > Cache createCache(String cacheName, - C configuration) throws IllegalArgumentException { + public > Cache createCache( + String cacheName, C configuration) { requireNotClosed(); requireNonNull(configuration); diff --git a/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheProxy.java b/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheProxy.java index 0ef03245d7..6adadd586f 100644 --- a/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheProxy.java +++ b/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheProxy.java @@ -746,8 +746,7 @@ public CaffeineConfiguration getConfiguration() { } @Override - public T invoke(K key, EntryProcessor entryProcessor, Object... arguments) - throws EntryProcessorException { + public T invoke(K key, EntryProcessor entryProcessor, Object... arguments) { requireNonNull(entryProcessor); requireNonNull(arguments); requireNotClosed(); @@ -961,7 +960,7 @@ private void publishToCacheWriter(Consumer action, Supplier data) { } /** Writes all of the entries to the cache writer if write-through is enabled. */ - private CacheWriterException writeAllToCacheWriter(Map map) { + private CacheWriterException writeAllToCacheWriter(Map map) { if (!configuration.isWriteThrough() || map.isEmpty()) { return null; } @@ -985,7 +984,7 @@ private CacheWriterException writeAllToCacheWriter(Map CacheWriterException deleteAllToCacheWriter(Set keys) { + private CacheWriterException deleteAllToCacheWriter(Set keys) { if (!configuration.isWriteThrough() || keys.isEmpty()) { return null; } diff --git a/jcache/src/main/java/com/github/benmanes/caffeine/jcache/configuration/TypesafeConfigurator.java b/jcache/src/main/java/com/github/benmanes/caffeine/jcache/configuration/TypesafeConfigurator.java index 7da1c9b97a..decb8fb663 100644 --- a/jcache/src/main/java/com/github/benmanes/caffeine/jcache/configuration/TypesafeConfigurator.java +++ b/jcache/src/main/java/com/github/benmanes/caffeine/jcache/configuration/TypesafeConfigurator.java @@ -212,6 +212,7 @@ public void addLazyExpiration() { Duration creation = getDurationFor("policy.lazy-expiration.creation"); Duration update = getDurationFor("policy.lazy-expiration.update"); Duration access = getDurationFor("policy.lazy-expiration.access"); + requireNonNull(creation, "policy.lazy-expiration.creation may not be null"); boolean eternal = Objects.equals(creation, Duration.ETERNAL) && Objects.equals(update, Duration.ETERNAL) diff --git a/jcache/src/main/java/com/github/benmanes/caffeine/jcache/spi/CaffeineCachingProvider.java b/jcache/src/main/java/com/github/benmanes/caffeine/jcache/spi/CaffeineCachingProvider.java index 9dee1b6cdd..4b98eedab3 100644 --- a/jcache/src/main/java/com/github/benmanes/caffeine/jcache/spi/CaffeineCachingProvider.java +++ b/jcache/src/main/java/com/github/benmanes/caffeine/jcache/spi/CaffeineCachingProvider.java @@ -15,6 +15,8 @@ */ package com.github.benmanes.caffeine.jcache.spi; +import static javax.cache.configuration.OptionalFeature.STORE_BY_REFERENCE; + import java.net.URI; import java.util.ArrayList; import java.util.HashMap; @@ -131,13 +133,8 @@ public void close(URI uri, ClassLoader classLoader) { } @Override - @SuppressWarnings("PMD.TooFewBranchesForASwitchStatement") public boolean isSupported(OptionalFeature optionalFeature) { - switch (optionalFeature) { - case STORE_BY_REFERENCE: - return true; - } - return false; + return (optionalFeature == STORE_BY_REFERENCE); } private URI getManagerUri(URI uri) { diff --git a/simulator/build.gradle b/simulator/build.gradle index a075be821c..7e17bdbaeb 100644 --- a/simulator/build.gradle +++ b/simulator/build.gradle @@ -38,6 +38,10 @@ coverity { skip = true } +sonarqube { + skipProject = true +} + tasks.withType(Javadoc) { options.addStringOption('Xdoclint:none', '-quiet') // https://github.com/akka/akka/issues/21165 diff --git a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/HashedItem.java b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/HashedItem.java index d24208167e..4a87765e1e 100644 --- a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/HashedItem.java +++ b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/HashedItem.java @@ -22,11 +22,11 @@ * * @author gilga1983@gmail.com (Gil Einziger) */ -public class HashedItem { - public int set; - public byte chainId; - public byte fingerprint; - public long value; +final class HashedItem { + int set; + byte chainId; + byte fingerprint; + long value; public HashedItem(int set, byte chainid, byte fingerprit, long value) { this.set = set; diff --git a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/PolicyStats.java b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/PolicyStats.java index e38ecfccd5..773f73b349 100644 --- a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/PolicyStats.java +++ b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/PolicyStats.java @@ -128,8 +128,8 @@ public double missRate() { } public double admissionRate() { - double candidateCount = admittedCount + rejectedCount; - return (candidateCount == 0) ? 1.0 : admittedCount / candidateCount; + long candidateCount = admittedCount + rejectedCount; + return (candidateCount == 0) ? 1.0 : (double) admittedCount / candidateCount; } public double complexity() { diff --git a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/product/OhcPolicy.java b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/product/OhcPolicy.java index 2892aadbce..e7b83a4106 100644 --- a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/product/OhcPolicy.java +++ b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/product/OhcPolicy.java @@ -40,7 +40,7 @@ * @author ben.manes@gmail.com (Ben Manes) */ public final class OhcPolicy implements Policy { - private static final int ENTRY_SIZE = 80; + private static final long ENTRY_SIZE = 80; private final OHCache cache; private final PolicyStats policyStats; diff --git a/travis.sh b/travis.sh index b5ea74c7d4..a7fc9612a1 100755 --- a/travis.sh +++ b/travis.sh @@ -25,10 +25,11 @@ case "${1:?''}" in run "sh -c 'cd examples/write-behind-rxjava && mvn test'" ;; tests) - run "./gradlew check --console plain" - runSlow "./gradlew :caffeine:slowCaffeineTest --console plain" - runSlow "./gradlew :caffeine:slowGuavaTest --console plain" + run "./gradlew check --scan --console plain" + runSlow "./gradlew :caffeine:slowCaffeineTest --scan --console plain" + runSlow "./gradlew :caffeine:slowGuavaTest --scan --console plain" run "./gradlew coveralls uploadArchives --console plain" + runSlow "./gradlew sonarqube --console plain" ;; *) echo $"Usage: $0 {analysis|tests}"