@Override public ByteBuffer encode(OffHeapValueHolder<V> valueHolder) { ByteBuffer serialized; if (valueHolder instanceof BinaryValueHolder && ((BinaryValueHolder)valueHolder).isBinaryValueAvailable()) { serialized = ((BinaryValueHolder)valueHolder).getBinaryValue(); } else { serialized = serializer.serialize(valueHolder.get()); } ByteBuffer byteBuffer = ByteBuffer.allocate(serialized.remaining() + FIELDS_OVERHEAD); byteBuffer.putLong(valueHolder.getId()); byteBuffer.putLong(valueHolder.creationTime()); byteBuffer.putLong(valueHolder.lastAccessTime()); byteBuffer.putLong(valueHolder.expirationTime()); byteBuffer.putLong(0L); // represent the hits on previous versions. It is kept for compatibility reasons with previously saved data byteBuffer.put(serialized); byteBuffer.flip(); return byteBuffer; }
BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>> computeFunction = (mappedKey, mappedValue) -> { long now = timeSource.getTimeMillis(); if (mappedValue == null || mappedValue.isExpired(now)) { if (mappedValue != null) { onExpirationInCachingTier(mappedValue, key); mappedValue.detach(); valueHolderAtomicReference.set(mappedValue); return null;
@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; } }
private OffHeapValueHolder<V> setAccessTimeAndExpiryThenReturnMapping(K key, OffHeapValueHolder<V> valueHolder, long now, StoreEventSink<K, V> eventSink) { Duration duration = Duration.ZERO; try { duration = expiry.getExpiryForAccess(key, valueHolder); if (duration != null && duration.isNegative()) { duration = Duration.ZERO; } } catch (RuntimeException re) { LOG.error("Expiry computation caused an exception - Expiry duration will be 0 ", re); } if (Duration.ZERO.equals(duration)) { onExpiration(key, valueHolder, eventSink); return null; } valueHolder.accessed(now, duration); valueHolder.writeBack(); return valueHolder; }
long now = timeSource.getTimeMillis(); if (mappedValue.isExpired(now)) { onExpiration(mappedKey, mappedValue, eventSink); return null; mappedValue.forceDeserialization(); OffHeapValueHolder<V> valueHolder = setAccessTimeAndExpiryThenReturnMapping(mappedKey, mappedValue, now, eventSink); if (valueHolder == null) { mappedValue.forceDeserialization();
long now = timeSource.getTimeMillis(); V existingValue = null; if (mappedValue == null || mappedValue.isExpired(now)) { if (mappedValue != null) { onExpiration(mappedKey, mappedValue, eventSink); existingValue = mappedValue.get(); existingValueHolder.set(mappedValue); OffHeapValueHolder<V> valueHolder = newUpdatedValueHolder(key, computedValue, mappedValue, now, eventSink); if (valueHolder == null) { valueHeld.set(new BasicOffHeapValueHolder<>(mappedValue.getId(), computedValue, now, now));
BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>> computeFunction = (mappedKey, mappedValue) -> { long now = timeSource.getTimeMillis(); if (mappedValue == null || mappedValue.isExpired(now)) { if (mappedValue != null) { onExpiration(mappedKey, mappedValue, eventSink); if (valueHolder != null) { if (delayedDeserialization) { mappedValue.detach(); } else { mappedValue.forceDeserialization();
@Test public void testDelayedDeserialization() { JavaSerializer<String> serializer = new JavaSerializer<>(getClass().getClassLoader()); String testValue = "Let's get binary!"; ByteBuffer serialized = serializer.serialize(testValue); OffHeapValueHolder<String> valueHolder = new LazyOffHeapValueHolder<>(1L, serialized, serializer, 10L, 20L, 15L, mock(WriteContext.class)); valueHolder.detach(); serialized.clear(); assertThat(valueHolder.get(), is(testValue)); }
@Test public void testWriteBackSupport() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { ByteBuffer encoded = valueHolderPortability.encode(originalValue); WriteContext writeContext = mock(WriteContext.class); OffHeapValueHolder<String> decoded = valueHolderPortability.decode(encoded, writeContext); decoded.setExpirationTime(4L); decoded.setLastAccessTime(6L); decoded.writeBack(); verify(writeContext).setLong(OffHeapValueHolderPortability.ACCESS_TIME_OFFSET, 6L); verify(writeContext).setLong(OffHeapValueHolderPortability.EXPIRE_TIME_OFFSET, 4L); }
if (mappedValue != null && mappedValue.isExpired(now)) { onExpiration(mappedKey, mappedValue, eventSink); return null;
private OffHeapValueHolder<V> newUpdatedValueHolder(K key, V value, OffHeapValueHolder<V> existing, long now, StoreEventSink<K, V> eventSink) { eventSink.updated(key, existing, value); Duration duration = Duration.ZERO; try { duration = expiry.getExpiryForUpdate(key, existing, value); if (duration != null && duration.isNegative()) { duration = Duration.ZERO; } } catch (RuntimeException re) { LOG.error("Expiry computation caused an exception - Expiry duration will be 0 ", re); } if (Duration.ZERO.equals(duration)) { eventSink.expired(key, () -> value); return null; } if (duration == null) { return new BasicOffHeapValueHolder<>(backingMap().nextIdFor(key), value, now, existing.expirationTime()); } else if (isExpiryDurationInfinite(duration)) { return new BasicOffHeapValueHolder<>(backingMap().nextIdFor(key), value, now, OffHeapValueHolder.NO_EXPIRE); } else { return new BasicOffHeapValueHolder<>(backingMap().nextIdFor(key), value, now, ExpiryUtils.getExpirationMillis(now, duration)); } }
@Test public void testWriteBackOfValueHolder() throws StoreAccessException { offHeapStore = createAndInitStore(timeSource, ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofMillis(15L))); offHeapStore.put("key1", "value1"); timeSource.advanceTime(10); OffHeapValueHolder<String> valueHolder = (OffHeapValueHolder<String>)offHeapStore.get("key1"); assertThat(valueHolder.lastAccessTime(), is(10L)); timeSource.advanceTime(10); assertThat(offHeapStore.get("key1"), notNullValue()); timeSource.advanceTime(16); assertThat(offHeapStore.get("key1"), nullValue()); }
long now = timeSource.getTimeMillis(); V existingValue = null; if (mappedValue == null || mappedValue.isExpired(now)) { if (mappedValue != null) { onExpiration(mappedKey, mappedValue, eventSink); existingValue = mappedValue.get(); OffHeapValueHolder<V> valueHolder = newUpdatedValueHolder(key, computedValue, mappedValue, now, eventSink); if (valueHolder == null) { valueHeld.set(new BasicOffHeapValueHolder<>(mappedValue.getId(), computedValue, now, now));
long now = timeSource.getTimeMillis(); if (mappedValue == null || mappedValue.isExpired(now)) { if (mappedValue != null) { onExpiration(mappedKey, mappedValue, eventSink); } else if (oldValue.equals(mappedValue.get())) { replaced.set(true); return newUpdatedValueHolder(mappedKey, newValue, mappedValue, now, eventSink);
BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>> computeFunction = (mappedKey, mappedValue) -> { long now = timeSource.getTimeMillis(); if (mappedValue == null || mappedValue.isExpired(now, TimeUnit.MILLISECONDS)) { if (mappedValue != null) { onExpiration(mappedKey, mappedValue, eventSink); if (valueHolder != null) { if (delayedDeserialization) { mappedValue.detach(); } else { mappedValue.forceDeserialization();
long now = timeSource.getTimeMillis(); if (mappedValue == null || mappedValue.isExpired(now)) { if (mappedValue != null) { onExpiration(mappedKey, mappedValue, eventSink); mappedValue.forceDeserialization(); returnValue.set(mappedValue); return setAccessTimeAndExpiryThenReturnMapping(mappedKey, mappedValue, now, eventSink);
@Override public int hashCode() { int result = 1; result = 31 * result + get().hashCode(); result = 31 * result + super.hashCode(); return result; }
private OffHeapValueHolder<V> setAccessTimeAndExpiryThenReturnMapping(K key, OffHeapValueHolder<V> valueHolder, long now, StoreEventSink<K, V> eventSink) { Duration duration = Duration.ZERO; try { duration = expiry.getExpiryForAccess(key, valueHolder); if (duration != null && duration.isNegative()) { duration = Duration.ZERO; } } catch (RuntimeException re) { LOG.error("Expiry computation caused an exception - Expiry duration will be 0 ", re); } if (Duration.ZERO.equals(duration)) { onExpiration(key, valueHolder, eventSink); return null; } valueHolder.accessed(now, duration); valueHolder.writeBack(); return valueHolder; }