@CacheSpec(implementation = Implementation.Caffeine, population = Population.EMPTY, maximumSize = Maximum.DISABLED, weigher = CacheWeigher.DEFAULT, expireAfterAccess = Expire.DISABLED, expireAfterWrite = Expire.DISABLED, refreshAfterWrite = Expire.DISABLED, keys = ReferenceType.STRONG, values = ReferenceType.STRONG) @Test(dataProvider = "caches") public void noPolicy_async(AsyncLoadingCache<Integer, Integer> cache, CacheContext context) { assertThat(cache.synchronous().policy().eviction(), is(Optional.empty())); assertThat(cache.synchronous().policy().expireAfterWrite(), is(Optional.empty())); assertThat(cache.synchronous().policy().expireAfterAccess(), is(Optional.empty())); assertThat(cache.synchronous().policy().refreshAfterWrite(), is(Optional.empty())); } }
public <K, V> AsyncLoadingCache<K, V> buildAsync(AsyncCacheLoader<K, V> loader) { checkState(isCaffeine() && isAsync()); AsyncLoadingCache<K, V> cache = caffeine.buildAsync(loader); this.cache = cache.synchronous(); return cache; }
public <K, V> AsyncLoadingCache<K, V> buildAsync(CacheLoader<K, V> loader) { checkState(isCaffeine() && isAsync()); AsyncLoadingCache<K, V> cache = caffeine.buildAsync(loader); this.cache = cache.synchronous(); return cache; }
@Test(dataProvider = "caches") @CacheSpec(requiresWeakOrSoft = true, expireAfterAccess = Expire.DISABLED, expireAfterWrite = Expire.DISABLED, maximumSize = Maximum.DISABLED, weigher = CacheWeigher.DEFAULT, population = Population.FULL, stats = Stats.ENABLED, removalListener = Listener.CONSUMING) public void getIfPresent(AsyncLoadingCache<Integer, Integer> cache, CacheContext context) { Integer key = context.firstKey(); Integer value = context.original().get(key); context.clear(); GcFinalization.awaitFullGc(); awaitFullCleanup(cache.synchronous()); assertThat(cache.synchronous().getIfPresent(key), is(value)); }
@Test(dataProvider = "caches") @CacheSpec(refreshAfterWrite = Expire.ONE_MINUTE, loader = Loader.NULL) public void get_null(AsyncLoadingCache<Integer, Integer> cache, CacheContext context) { Integer key = 1; cache.synchronous().put(key, key); context.ticker().advance(2, TimeUnit.MINUTES); await().until(() -> cache.synchronous().getIfPresent(key), is(nullValue())); }
@Test(dataProvider = "caches") @CacheSpec(keys = ReferenceType.WEAK, values = ReferenceType.STRONG, expireAfterAccess = Expire.DISABLED, expireAfterWrite = Expire.DISABLED, maximumSize = Maximum.DISABLED, weigher = CacheWeigher.DEFAULT, population = Population.FULL, stats = Stats.ENABLED, loader = {Loader.NEGATIVE, Loader.BULK_NEGATIVE}, removalListener = Listener.CONSUMING) public void getAll(AsyncLoadingCache<Integer, Integer> cache, CacheContext context) { Set<Integer> keys = ImmutableSet.of(context.firstKey(), context.lastKey(), context.absentKey()); context.clear(); GcFinalization.awaitFullGc(); assertThat(cache.getAll(keys).join(), is(keys.stream().collect(toMap(Function.identity(), key -> -key)))); long count = context.initialSize() - cache.synchronous().estimatedSize() + 1; assertThat(count, is(greaterThan((long) keys.size()))); assertThat(cache, hasRemovalNotifications(context, count, RemovalCause.COLLECTED)); verifyWriter(context, (verifier, writer) -> verifier.deletions(count, RemovalCause.COLLECTED)); }
@Test(dataProvider = "caches") @CacheSpec(population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }) public void put_replace(AsyncLoadingCache<Integer, Integer> cache, CacheContext context) { CompletableFuture<Integer> value = CompletableFuture.completedFuture(context.absentValue()); for (Integer key : context.firstMiddleLastKeys()) { cache.put(key, value); assertThat(cache.get(key), is(futureOf(context.absentValue()))); } assertThat(cache.synchronous().estimatedSize(), is(context.initialSize())); int count = context.firstMiddleLastKeys().size(); assertThat(cache, hasRemovalNotifications(context, count, RemovalCause.REPLACED)); }
@CheckNoWriter @Test(dataProvider = "caches") @CacheSpec(loader = { Loader.BULK_NEGATIVE_EXCEEDS }, removalListener = { Listener.DEFAULT, Listener.REJECTING }) public void getAll_exceeds(AsyncLoadingCache<Integer, Integer> cache, CacheContext context) { Map<Integer, Integer> result = cache.getAll(context.absentKeys()).join(); assertThat(result.keySet(), equalTo(context.absentKeys())); assertThat(cache.synchronous().estimatedSize(), is(greaterThan(context.initialSize() + context.absentKeys().size()))); assertThat(context, both(hasMissCount(result.size())).and(hasHitCount(0))); assertThat(context, both(hasLoadSuccessCount(1)).and(hasLoadFailureCount(0))); }
@Test(dataProvider = "caches") @CacheSpec(keys = ReferenceType.WEAK, values = ReferenceType.STRONG, expireAfterAccess = Expire.DISABLED, expireAfterWrite = Expire.DISABLED, maximumSize = Maximum.DISABLED, weigher = CacheWeigher.DEFAULT, population = Population.FULL, stats = Stats.ENABLED, removalListener = Listener.CONSUMING) public void put(AsyncLoadingCache<Integer, Integer> cache, CacheContext context) { Integer key = context.absentKey(); context.clear(); GcFinalization.awaitFullGc(); cache.put(key, CompletableFuture.completedFuture(context.absentValue())); long count = context.initialSize(); assertThat(cache.synchronous().estimatedSize(), is(1L)); assertThat(cache, hasRemovalNotifications(context, count, RemovalCause.COLLECTED)); }
@Test(dataProvider = "caches") @CacheSpec(population = { Population.PARTIAL, Population.FULL }, mustExpireWithAnyOf = { AFTER_WRITE, VARIABLE }, expireAfterWrite = Expire.ONE_MINUTE, expiry = { CacheExpiry.DISABLED, CacheExpiry.WRITE }, expiryTime = Expire.ONE_MINUTE) @SuppressWarnings("FutureReturnValueIgnored") public void getIfPresent(AsyncLoadingCache<Integer, Integer> cache, CacheContext context) { context.ticker().advance(30, TimeUnit.SECONDS); cache.getIfPresent(context.firstKey()); context.ticker().advance(45, TimeUnit.SECONDS); assertThat(cache.getIfPresent(context.firstKey()), is(nullValue())); assertThat(cache.getIfPresent(context.lastKey()), is(nullValue())); assertThat(cache.synchronous().estimatedSize(), is(0L)); long count = context.initialSize(); assertThat(cache, hasRemovalNotifications(context, count, RemovalCause.EXPIRED)); }
@Test(dataProvider = "caches", timeOut = 5000) // Issue #69 @CacheSpec(implementation = Implementation.Caffeine, population = Population.EMPTY, executor = CacheExecutor.THREADED, compute = Compute.ASYNC, values = ReferenceType.STRONG) public void refresh_deadlock(CacheContext context) { CompletableFuture<Integer> future = new CompletableFuture<>(); AsyncLoadingCache<Integer, Integer> cache = context.buildAsync((k, e) -> future); cache.synchronous().refresh(context.absentKey()); CompletableFuture<Integer> get = cache.get(context.absentKey()); future.complete(context.absentValue()); assertThat(get, futureOf(context.absentValue())); }
@Test(dataProvider = "caches") @CacheSpec(population = Population.FULL, mustExpireWithAnyOf = { AFTER_ACCESS, AFTER_WRITE, VARIABLE }, expiry = { CacheExpiry.DISABLED, CacheExpiry.CREATE, CacheExpiry.WRITE, CacheExpiry.ACCESS }, expireAfterAccess = {Expire.DISABLED, Expire.ONE_MINUTE}, expiryTime = Expire.ONE_MINUTE, expireAfterWrite = {Expire.DISABLED, Expire.ONE_MINUTE}) public void put_insert(AsyncLoadingCache<Integer, Integer> cache, CacheContext context) { context.ticker().advance(1, TimeUnit.MINUTES); cache.put(context.firstKey(), CompletableFuture.completedFuture(context.absentValue())); runVariableExpiration(context); long count = context.initialSize(); assertThat(cache.synchronous().estimatedSize(), is(1L)); assertThat(cache, hasRemovalNotifications(context, count, RemovalCause.EXPIRED)); }
@Test(dataProvider = "caches") @CacheSpec(mustExpireWithAnyOf = { AFTER_ACCESS, VARIABLE }, expiry = { CacheExpiry.DISABLED, CacheExpiry.ACCESS }, expiryTime = Expire.ONE_MINUTE, expireAfterAccess = Expire.ONE_MINUTE, population = { Population.PARTIAL, Population.FULL }) @SuppressWarnings("FutureReturnValueIgnored") public void getIfPresent(AsyncLoadingCache<Integer, Integer> cache, CacheContext context) { context.ticker().advance(30, TimeUnit.SECONDS); cache.getIfPresent(context.firstKey()); context.ticker().advance(45, TimeUnit.SECONDS); assertThat(cache.getIfPresent(context.firstKey()), is(futureOf(-context.firstKey()))); assertThat(cache.getIfPresent(context.lastKey()), is(nullValue())); assertThat(cache.synchronous().estimatedSize(), is(1L)); long count = context.initialSize() - 1; assertThat(cache, hasRemovalNotifications(context, count, RemovalCause.EXPIRED)); }
@CheckNoWriter @Test(dataProvider = "caches") @CacheSpec(refreshAfterWrite = Expire.ONE_MINUTE, loader = Loader.NEGATIVE, population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }) public void getIfPresent(AsyncLoadingCache<Integer, Integer> cache, CacheContext context) { context.ticker().advance(30, TimeUnit.SECONDS); assertThat(cache.getIfPresent(context.middleKey()), is(futureOf(-context.middleKey()))); context.ticker().advance(45, TimeUnit.SECONDS); assertThat(cache.getIfPresent(context.middleKey()), is(futureOf(-context.middleKey()))); assertThat(cache.synchronous().estimatedSize(), is(context.initialSize())); assertThat(cache, hasRemovalNotifications(context, 1, RemovalCause.REPLACED)); }
@Test(dataProvider = "caches") @CacheSpec(population = Population.EMPTY, expiryTime = Expire.ONE_MINUTE, mustExpireWithAnyOf = { AFTER_WRITE, VARIABLE }, expiry = { CacheExpiry.DISABLED, CacheExpiry.WRITE }, expireAfterWrite = {Expire.DISABLED, Expire.ONE_MINUTE}) @SuppressWarnings("FutureReturnValueIgnored") public void get_writeTime(AsyncLoadingCache<Integer, Integer> cache, CacheContext context) { Integer key = context.absentKey(); Integer value = context.absentValue(); cache.get(key, k -> { context.ticker().advance(5, TimeUnit.MINUTES); return value; }); assertThat(cache.synchronous().estimatedSize(), is(1L)); assertThat(cache.getIfPresent(key), futureOf(value)); }
@CheckNoWriter @Test(dataProvider = "caches") @CacheSpec(refreshAfterWrite = Expire.ONE_MINUTE, population = { Population.PARTIAL, Population.FULL }) @SuppressWarnings("FutureReturnValueIgnored") public void getFunc(AsyncLoadingCache<Integer, Integer> cache, CacheContext context) { Function<Integer, Integer> mappingFunction = context.original()::get; context.ticker().advance(30, TimeUnit.SECONDS); cache.get(context.firstKey(), mappingFunction); context.ticker().advance(45, TimeUnit.SECONDS); cache.get(context.lastKey(), mappingFunction); // refreshed assertThat(cache.synchronous().estimatedSize(), is(context.initialSize())); assertThat(cache, hasRemovalNotifications(context, 1, RemovalCause.REPLACED)); }
@CheckNoWriter @Test(dataProvider = "caches") @CacheSpec(loader = Loader.EXCEPTIONAL, executor = CacheExecutor.THREADED, executorFailure = ExecutorFailure.IGNORED) public void get_absent_failure_async(AsyncLoadingCache<Integer, Integer> cache, CacheContext context) throws InterruptedException { AtomicBoolean done = new AtomicBoolean(); Integer key = context.absentKey(); CompletableFuture<Integer> valueFuture = cache.get(key); valueFuture.whenComplete((r, e) -> done.set(true)); Awaits.await().untilTrue(done); Awaits.await().until(() -> !cache.synchronous().asMap().containsKey(context.absentKey())); Awaits.await().until(() -> context, both(hasMissCount(1)).and(hasHitCount(0))); Awaits.await().until(() -> context, both(hasLoadSuccessCount(0)).and(hasLoadFailureCount(1))); assertThat(valueFuture.isCompletedExceptionally(), is(true)); assertThat(cache.getIfPresent(key), is(nullValue())); }
public <K, V> LoadingCache<K, V> build(CacheLoader<K, V> loader) { LoadingCache<K, V> cache; if (isCaffeine()) { cache = isAsync() ? caffeine.buildAsync(loader).synchronous() : caffeine.build(loader); } else { cache = new GuavaLoadingCache<>(guava.build( com.google.common.cache.CacheLoader.asyncReloading( new SingleLoader<>(loader), executor)), ticker, isRecordingStats()); } this.cache = cache; return cache; }
private static void addUnboundedTests(TestSuite suite) throws Exception { suite.addTest(MapTestFactory.suite("UnboundedCache", () -> { Cache<String, String> cache = Caffeine.newBuilder().build(); return cache.asMap(); })); suite.addTest(MapTestFactory.suite("UnboundedAsyncCache", () -> { AsyncLoadingCache<String, String> cache = Caffeine.newBuilder().buildAsync(key -> null); return cache.synchronous().asMap(); })); }
private static void addBoundedTests(TestSuite suite) throws Exception { suite.addTest(MapTestFactory.suite("BoundedCache", () -> { Cache<String, String> cache = Caffeine.newBuilder().maximumSize(Long.MAX_VALUE).build(); return cache.asMap(); })); suite.addTest(MapTestFactory.suite("BoundedAsyncCache", () -> { AsyncLoadingCache<String, String> cache = Caffeine.newBuilder() .maximumSize(Long.MAX_VALUE) .buildAsync(key -> null); return cache.synchronous().asMap(); })); }