@Test public void testExpiryUpdateException() throws Exception { final TestTimeSource timeSource = new TestTimeSource(); AbstractOffHeapStore<String, String> offHeapStore = createAndInitStore( timeSource, new Expiry<String, String>() { @Override public Duration getExpiryForCreation(String key, String value) { return Duration.FOREVER; } @Override public Duration getExpiryForAccess(String key, String value) { return Duration.FOREVER; } @Override public Duration getExpiryForUpdate(String key, String oldValue, String newValue) { if (timeSource.getTimeMillis() > 0) { throw new RuntimeException(); } return Duration.FOREVER; } }); offHeapStore.put("key", "value"); assertThat(offHeapStore.get("key").value(), is("value")); timeSource.advanceTime(1000); offHeapStore.put("key", "newValue"); assertNull(offHeapStore.get("key")); }
@Test public void testExpiryAccessException() throws Exception { TestTimeSource timeSource = new TestTimeSource(); AbstractOffHeapStore<String, String> offHeapStore = createAndInitStore( timeSource, new Expiry<String, String>() { @Override public Duration getExpiryForCreation(String key, String value) { return Duration.FOREVER; } @Override public Duration getExpiryForAccess(String key, String value) { throw new RuntimeException(); } @Override public Duration getExpiryForUpdate(String key, String oldValue, String newValue) { return null; } }); offHeapStore.put("key", "value"); assertNull(offHeapStore.get("key")); }
@Test public void testWriteBackOfValueHolder() throws CacheAccessException { TestTimeSource timeSource = new TestTimeSource(); AbstractOffHeapStore<String, String> offHeapStore = createAndInitStore( timeSource, Expirations.timeToIdleExpiration(new Duration(15L, TimeUnit.MILLISECONDS))); try { offHeapStore.put("key1", "value1"); timeSource.advanceTime(10); OffHeapValueHolder<String> valueHolder = (OffHeapValueHolder<String>) offHeapStore.get("key1"); assertThat(valueHolder.lastAccessTime(TimeUnit.MILLISECONDS), is(10L)); timeSource.advanceTime(10); assertThat(offHeapStore.get("key1"), notNullValue()); timeSource.advanceTime(16); assertThat(offHeapStore.get("key1"), nullValue()); } finally { destroyStore(offHeapStore); } }
@Test public void testClear() throws Exception { final TestTimeSource timeSource = new TestTimeSource(); AbstractOffHeapStore<String, String> offHeapStore = createAndInitStore( timeSource, Expirations.timeToIdleExpiration(new Duration(15L, TimeUnit.MILLISECONDS))); try { offHeapStore.put("1", "one"); offHeapStore.put("2", "two"); offHeapStore.put("3", "three"); offHeapStore.clear(); assertThat(offHeapStore.get("1"), is(nullValue())); assertThat(offHeapStore.get("2"), is(nullValue())); assertThat(offHeapStore.get("3"), is(nullValue())); } finally { destroyStore(offHeapStore); } }
@Test public void testExpiryEventFiredOnExpiredCachedEntry() throws CacheAccessException { TestTimeSource timeSource = new TestTimeSource(); AbstractOffHeapStore<String, String> offHeapStore = createAndInitStore( timeSource, Expirations.timeToIdleExpiration(new Duration(10L, TimeUnit.MILLISECONDS))); try { final List<String> expiredKeys = new ArrayList<String>(); offHeapStore.enableStoreEventNotifications( new StoreEventListener<String, String>() { @Override public void onEviction(final String key, final Store.ValueHolder<String> valueHolder) { throw new AssertionError("This should not have happened."); } @Override public void onExpiration( final String key, final Store.ValueHolder<String> valueHolder) { expiredKeys.add(key); } }); offHeapStore.put("key1", "value1"); offHeapStore.put("key2", "value2"); offHeapStore.get("key1"); // Bring the entry to the caching tier timeSource.advanceTime(11); // Expire the elements offHeapStore.get("key1"); offHeapStore.get("key2"); assertThat(expiredKeys, containsInAnyOrder("key1", "key2")); assertThat( getExpirationStatistic(offHeapStore) .count(StoreOperationOutcomes.ExpirationOutcome.SUCCESS), is(2L)); } finally { destroyStore(offHeapStore); } }
@Test public void testInvalidateKeyWithFunction() throws Exception { final TestTimeSource timeSource = new TestTimeSource(); AbstractOffHeapStore<String, String> offHeapStore = createAndInitStore( timeSource, Expirations.timeToIdleExpiration(new Duration(15L, TimeUnit.MILLISECONDS))); try { final AtomicReference<Store.ValueHolder<String>> invalidated = new AtomicReference<Store.ValueHolder<String>>(); offHeapStore.setInvalidationListener( new CachingTier.InvalidationListener<String, String>() { @Override public void onInvalidation(String key, Store.ValueHolder<String> valueHolder) { invalidated.set(valueHolder); } }); final AtomicBoolean functionInvoked = new AtomicBoolean(false); NullaryFunction<String> nullaryFunction = new NullaryFunction<String>() { @Override public String apply() { functionInvoked.set(true); return ""; } }; offHeapStore.invalidate("1", nullaryFunction); assertThat(invalidated.get(), is(nullValue())); assertThat(functionInvoked.get(), is(true)); validateStats( offHeapStore, EnumSet.of(LowerCachingTierOperationsOutcome.InvalidateOutcome.MISS)); functionInvoked.set(false); offHeapStore.put("1", "one"); offHeapStore.invalidate("1", nullaryFunction); assertThat(invalidated.get().value(), equalTo("one")); assertThat(functionInvoked.get(), is(true)); validateStats( offHeapStore, EnumSet.of( LowerCachingTierOperationsOutcome.InvalidateOutcome.MISS, LowerCachingTierOperationsOutcome.InvalidateOutcome.REMOVED)); assertThat(offHeapStore.get("1"), is(nullValue())); } finally { destroyStore(offHeapStore); } }
@Test public void testGetAndRemoveValue() throws Exception { TestTimeSource timeSource = new TestTimeSource(); AbstractOffHeapStore<String, String> offHeapStore = createAndInitStore(timeSource, Expirations.noExpiration()); try { offHeapStore.put("1", "one"); assertThat(offHeapStore.getAndRemove("1").value(), equalTo("one")); validateStats( offHeapStore, EnumSet.of(LowerCachingTierOperationsOutcome.GetAndRemoveOutcome.HIT_REMOVED)); assertThat(offHeapStore.get("1"), is(nullValue())); } finally { destroyStore(offHeapStore); } }