From f11108a85091a13867e9e79d17f81e45eaeefcf3 Mon Sep 17 00:00:00 2001 From: Ben Manes Date: Sat, 23 Apr 2016 12:38:17 -0700 Subject: [PATCH] Improved Guava view (entrySet#iterator) compatibility --- .../benmanes/caffeine/cache/EvictionTest.java | 2 +- .../caffeine/guava/CaffeinatedGuavaCache.java | 29 ++++--- .../caffeine/cache/BoundedMapTests.java | 37 --------- .../caffeine/cache/CaffeineMapTests.java | 75 +++++++++++++++++++ .../caffeine/cache/MapTestFactory.java | 11 ++- .../caffeine/cache/UnboundedMapTests.java | 35 --------- 6 files changed, 99 insertions(+), 90 deletions(-) delete mode 100644 guava/src/test/java/com/github/benmanes/caffeine/cache/BoundedMapTests.java create mode 100644 guava/src/test/java/com/github/benmanes/caffeine/cache/CaffeineMapTests.java delete mode 100644 guava/src/test/java/com/github/benmanes/caffeine/cache/UnboundedMapTests.java diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/EvictionTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/EvictionTest.java index a150f97abb..070591693b 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/EvictionTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/EvictionTest.java @@ -220,8 +220,8 @@ public void evict_weighted_async(AsyncLoadingCache cache, ready.set(true); Awaits.await().untilTrue(done); - Awaits.await().until(() -> eviction.weightedSize().getAsLong(), is(10L)); Awaits.await().until(() -> cache.synchronous().estimatedSize(), is(2L)); + Awaits.await().until(() -> eviction.weightedSize().getAsLong(), is(10L)); assertThat(context, hasRemovalNotifications(context, 1, RemovalCause.SIZE)); verifyWriter(context, (verifier, writer) -> verifier.deletions(1, RemovalCause.SIZE)); } 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 979f1fbb75..060ef809ba 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 @@ -36,6 +36,7 @@ import com.google.common.cache.CacheStats; import com.google.common.collect.ForwardingCollection; import com.google.common.collect.ForwardingConcurrentMap; +import com.google.common.collect.ForwardingIterator; import com.google.common.collect.ForwardingMapEntry; import com.google.common.collect.ForwardingSet; import com.google.common.collect.ImmutableMap; @@ -199,17 +200,23 @@ public ConcurrentMap asMap() { } @Override public Iterator> iterator() { - return delegate().stream().map(entry -> { - Entry e = new ForwardingMapEntry() { - @Override public V setValue(V value) { - throw new UnsupportedOperationException(); - } - @Override protected Entry delegate() { - return entry; - } - }; - return e; - }).iterator(); + Iterator> iterator = delegate().iterator(); + return new ForwardingIterator>() { + @Override public Entry next() { + Entry entry = delegate().next(); + return new ForwardingMapEntry() { + @Override public V setValue(V value) { + throw new UnsupportedOperationException(); + } + @Override protected Entry delegate() { + return entry; + } + }; + } + @Override protected Iterator> delegate() { + return iterator; + } + }; } @Override protected Set> delegate() { return cache.asMap().entrySet(); diff --git a/guava/src/test/java/com/github/benmanes/caffeine/cache/BoundedMapTests.java b/guava/src/test/java/com/github/benmanes/caffeine/cache/BoundedMapTests.java deleted file mode 100644 index de668f54df..0000000000 --- a/guava/src/test/java/com/github/benmanes/caffeine/cache/BoundedMapTests.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2015 Ben Manes. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.github.benmanes.caffeine.cache; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -/** - * Guava testlib map tests for the bounded {@link Cache#asMap()} view. - * - * @author ben.manes@gmail.com (Ben Manes) - */ -public final class BoundedMapTests extends TestCase { - - public static Test suite() throws NoSuchMethodException, SecurityException { - TestSuite suite = new TestSuite(); - suite.addTest(MapTestFactory.suite("BoundedLocalCache", - Caffeine.newBuilder().maximumSize(Long.MAX_VALUE), false)); - suite.addTest(MapTestFactory.suite("BoundedLocalAsyncCache", - Caffeine.newBuilder().maximumSize(Long.MAX_VALUE), true)); - return suite; - } -} diff --git a/guava/src/test/java/com/github/benmanes/caffeine/cache/CaffeineMapTests.java b/guava/src/test/java/com/github/benmanes/caffeine/cache/CaffeineMapTests.java new file mode 100644 index 0000000000..998cf856e3 --- /dev/null +++ b/guava/src/test/java/com/github/benmanes/caffeine/cache/CaffeineMapTests.java @@ -0,0 +1,75 @@ +/* + * Copyright 2015 Ben Manes. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.benmanes.caffeine.cache; + +import com.github.benmanes.caffeine.guava.CaffeinatedGuava; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Guava testlib map tests for the {@link Cache#asMap()} view. + * + * @author ben.manes@gmail.com (Ben Manes) + */ +public final class CaffeineMapTests extends TestCase { + + public static Test suite() throws Exception { + TestSuite suite = new TestSuite(); + addGuavaViewTests(suite); + addUnboundedTests(suite); + addBoundedTests(suite); + return suite; + } + + private static void addUnboundedTests(TestSuite suite) throws Exception { + suite.addTest(MapTestFactory.suite("UnboundedCache", () -> { + Cache cache = Caffeine.newBuilder().build(); + return cache.asMap(); + })); + suite.addTest(MapTestFactory.suite("UnboundedAsyncCache", () -> { + AsyncLoadingCache cache = Caffeine.newBuilder().buildAsync(key -> null); + return cache.synchronous().asMap(); + })); + } + + private static void addBoundedTests(TestSuite suite) throws Exception { + suite.addTest(MapTestFactory.suite("BoundedCache", () -> { + Cache cache = Caffeine.newBuilder().maximumSize(Long.MAX_VALUE).build(); + return cache.asMap(); + })); + suite.addTest(MapTestFactory.suite("BoundedAsyncCache", () -> { + AsyncLoadingCache cache = Caffeine.newBuilder() + .maximumSize(Long.MAX_VALUE) + .buildAsync(key -> null); + return cache.synchronous().asMap(); + })); + } + + private static void addGuavaViewTests(TestSuite suite) throws Exception { + suite.addTest(MapTestFactory.suite("GuavaView", () -> { + com.google.common.cache.Cache cache = CaffeinatedGuava.build( + Caffeine.newBuilder().maximumSize(Long.MAX_VALUE)); + return cache.asMap(); + })); + suite.addTest(MapTestFactory.suite("GuavaLoadingView", () -> { + com.google.common.cache.Cache cache = CaffeinatedGuava.build( + Caffeine.newBuilder().maximumSize(Long.MAX_VALUE), key -> null); + return cache.asMap(); + })); + } +} diff --git a/guava/src/test/java/com/github/benmanes/caffeine/cache/MapTestFactory.java b/guava/src/test/java/com/github/benmanes/caffeine/cache/MapTestFactory.java index 5055d5f468..cf5808f64f 100644 --- a/guava/src/test/java/com/github/benmanes/caffeine/cache/MapTestFactory.java +++ b/guava/src/test/java/com/github/benmanes/caffeine/cache/MapTestFactory.java @@ -17,6 +17,7 @@ import java.util.Map; import java.util.Map.Entry; +import java.util.function.Supplier; import com.google.common.collect.testing.MapTestSuiteBuilder; import com.google.common.collect.testing.TestStringMapGenerator; @@ -39,18 +40,15 @@ private MapTestFactory() {} * Returns a test suite. * * @param name the name of the cache type under test - * @param builder the preconfigured cache builder - * @param async if the cache is asynchronous + * @param supplier the cache as a map * @return a suite of tests */ - protected static Test suite(String name, Caffeine builder, boolean async) + protected static Test suite(String name, Supplier> supplier) throws NoSuchMethodException, SecurityException { return MapTestSuiteBuilder .using(new TestStringMapGenerator() { @Override protected Map create(Entry[] entries) { - Map map = async - ? builder.buildAsync(key -> null).synchronous().asMap() - : builder.build().asMap(); + Map map = supplier.get(); for (Entry entry : entries) { map.put(entry.getKey(), entry.getValue()); } @@ -60,6 +58,7 @@ protected static Test suite(String name, Caffeine builder, boole .named(name) .withFeatures( MapFeature.GENERAL_PURPOSE, + MapFeature.ALLOWS_NULL_ENTRY_QUERIES, CollectionFeature.SUPPORTS_ITERATOR_REMOVE, CollectionSize.ANY) .createTestSuite(); diff --git a/guava/src/test/java/com/github/benmanes/caffeine/cache/UnboundedMapTests.java b/guava/src/test/java/com/github/benmanes/caffeine/cache/UnboundedMapTests.java deleted file mode 100644 index 2260bd7406..0000000000 --- a/guava/src/test/java/com/github/benmanes/caffeine/cache/UnboundedMapTests.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2015 Ben Manes. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.github.benmanes.caffeine.cache; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -/** - * Guava testlib map tests for the unbounded {@link Cache#asMap()} view. - * - * @author ben.manes@gmail.com (Ben Manes) - */ -public final class UnboundedMapTests extends TestCase { - - public static Test suite() throws NoSuchMethodException, SecurityException { - TestSuite suite = new TestSuite(); - suite.addTest(MapTestFactory.suite("UnoundedLocalCache", Caffeine.newBuilder(), false)); - suite.addTest(MapTestFactory.suite("UnoundedLocalAsyncCache", Caffeine.newBuilder(), true)); - return suite; - } -}