@Test public void testComputeIfPinnedClearsPinWithoutChangingValue() throws Exception { EhcacheOffHeapBackingMap<String, String> segment = createTestSegment(); final String value = "value"; try { putPinned("key", value, segment); boolean result = segment.computeIfPinned("key", (s, s2) -> { assertThat(s2, is(value)); return s2; }, s -> { assertThat(s, is(value)); return true; }); assertThat(isPinned("key", segment), is(false)); assertThat(result, is(true)); } finally { destroySegment(segment); } }
@Test public void testComputeIfPinnedReplacesValueUnpinnedWhenUnpinFunctionTrue() throws Exception { EhcacheOffHeapBackingMap<String, String> segment = createTestSegment(); final String value = "value"; final String newValue = "newValue"; try { putPinned("key", value, segment); boolean result = segment.computeIfPinned("key", (s, s2) -> { assertThat(s2, is(value)); return newValue; }, s -> { assertThat(s, is(value)); return true; }); assertThat(segment.get("key"), is(newValue)); assertThat(isPinned("key", segment), is(false)); assertThat(result, is(false)); } finally { destroySegment(segment); } }
@Test public void testComputeIfPinnedClearsMappingOnNullReturnWithPinningFalse() throws Exception { EhcacheOffHeapBackingMap<String, String> segment = createTestSegment(); final String value = "value"; try { putPinned("key", value, segment); boolean result = segment.computeIfPinned("key", (s, s2) -> { assertThat(s2, is(value)); return null; }, s -> { assertThat(s, is(value)); return false; }); assertThat(segment.containsKey("key"), is(false)); assertThat(result, is(true)); } finally { destroySegment(segment); } }
@Test public void testComputeIfPinnedClearsMappingOnNullReturnWithPinningTrue() throws Exception { EhcacheOffHeapBackingMap<String, String> segment = createTestSegment(); final String value = "value"; try { putPinned("key", value, segment); boolean result = segment.computeIfPinned("key", (s, s2) -> { assertThat(s2, is(value)); return null; }, s -> { assertThat(s, is(value)); return true; }); assertThat(segment.containsKey("key"), is(false)); assertThat(result, is(true)); } finally { destroySegment(segment); } }
@Test public void testComputeIfPinnedPreservesPinWithoutChangingValue() throws Exception { EhcacheOffHeapBackingMap<String, String> segment = createTestSegment(); final String value = "value"; try { putPinned("key", value, segment); boolean result = segment.computeIfPinned("key", (s, s2) -> { assertThat(s2, is(value)); return s2; }, s -> { assertThat(s, is(value)); return false; }); assertThat(isPinned("key", segment), is(true)); assertThat(result, is(false)); } finally { destroySegment(segment); } }
@Test public void testComputeIfPinnedReplacesValueUnpinnedWhenUnpinFunctionFalse() throws Exception { EhcacheOffHeapBackingMap<String, String> segment = createTestSegment(); final String value = "value"; final String newValue = "newValue"; try { putPinned("key", value, segment); boolean result = segment.computeIfPinned("key", (s, s2) -> { assertThat(s2, is(value)); return newValue; }, s -> { assertThat(s, is(value)); return false; }); assertThat(segment.get("key"), is(newValue)); assertThat(isPinned("key", segment), is(false)); assertThat(result, is(false)); } finally { destroySegment(segment); } }
@Test public void testComputeIfPinnedNoOpUnpinned() throws Exception { EhcacheOffHeapBackingMap<String, String> segment = createTestSegment(); try { segment.put("key", "value"); boolean result = segment.computeIfPinned("key", (s, s2) -> { fail("Method should not be invoked"); return null; }, s -> { fail("Method should not be invoked"); return false; }); assertThat(isPinned("key", segment), is(false)); assertThat(result, is(false)); } finally { destroySegment(segment); } }
@Override public boolean flush(K key, final ValueHolder<V> valueFlushed) { checkKey(key); flushObserver.begin(); final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink(); try { boolean result = backingMap().computeIfPinned(key, (k, valuePresent) -> { if (valuePresent.getId() == valueFlushed.getId()) { if (valueFlushed.isExpired(timeSource.getTimeMillis())) { onExpiration(k, valuePresent, eventSink); return null; } valuePresent.updateMetadata(valueFlushed); valuePresent.writeBack(); } return valuePresent; }, valuePresent -> valuePresent.getId() == valueFlushed.getId()); eventDispatcher.releaseEventSink(eventSink); if (result) { flushObserver.end(AuthoritativeTierOperationOutcomes.FlushOutcome.HIT); return true; } else { flushObserver.end(AuthoritativeTierOperationOutcomes.FlushOutcome.MISS); return false; } } catch (RuntimeException re) { eventDispatcher.releaseEventSinkAfterFailure(eventSink, re); throw re; } }
@Override public boolean flush(K key, final ValueHolder<V> valueFlushed) { checkKey(key); flushObserver.begin(); final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink(); try { boolean result = backingMap().computeIfPinned(key, (k, valuePresent) -> { if (valuePresent.getId() == valueFlushed.getId()) { if (valueFlushed.isExpired(timeSource.getTimeMillis(), TimeUnit.MILLISECONDS)) { onExpiration(k, valuePresent, eventSink); return null; } valuePresent.updateMetadata(valueFlushed); valuePresent.writeBack(); } return valuePresent; }, valuePresent -> valuePresent.getId() == valueFlushed.getId()); eventDispatcher.releaseEventSink(eventSink); if (result) { flushObserver.end(AuthoritativeTierOperationOutcomes.FlushOutcome.HIT); return true; } else { flushObserver.end(AuthoritativeTierOperationOutcomes.FlushOutcome.MISS); return false; } } catch (RuntimeException re) { eventDispatcher.releaseEventSinkAfterFailure(eventSink, re); throw re; } }