StoreEventSourceWrapper(StoreEventSource<K, SoftLock<V>> underlying) { this.underlying = underlying; underlying.addEventFilter((type, key, oldValue, newValue) -> { if (newValue != null) { return newValue.getOldValue() != null; } else if (oldValue != null) { return oldValue.getOldValue() != null; } return false; }); }
@Override public boolean adviseAgainstEviction(K key, SoftLock<V> softLock) { return isInDoubt(softLock) || wrappedEvictionAdvisor.adviseAgainstEviction(key, softLock.getOldValue()); } }
@Override public V getOldValue() { SoftLock<V> oldValue = delegate.getOldValue(); if (oldValue == null) { return null; } else { return oldValue.getOldValue(); } } }
@Override public V getNewValue() { SoftLock<V> newValue = delegate.getNewValue(); if (newValue == null) { return null; } else { return newValue.getOldValue(); } }
@Override public void addEventFilter(final StoreEventFilter<K, V> eventFilter) { underlying.addEventFilter((type, key, oldValue, newValue) -> { V unwrappedOldValue = null; V unwrappedNewValue = null; if (oldValue != null) { unwrappedOldValue = oldValue.getOldValue(); } if (newValue != null) { unwrappedNewValue = newValue.getOldValue(); } if (unwrappedNewValue == null && unwrappedOldValue == null) { return false; } return eventFilter.acceptEvent(type, key, unwrappedOldValue, unwrappedNewValue); }); }
@Override public Duration getExpiryForAccess(K key, Supplier<? extends SoftLock<V>> softLock) { if (softLock.get().getTransactionId() != null) { // phase 1 prepare, access -> forever return ExpiryPolicy.INFINITE; } else { // phase 2 commit, or during a TX's lifetime, access -> some time Duration duration; try { duration = configuredExpiry.getExpiryForAccess(key, () -> softLock.get().getOldValue()); } catch (RuntimeException re) { LOGGER.error("Expiry computation caused an exception - Expiry duration will be 0 ", re); return Duration.ZERO; } return duration; } }
@Override public Duration getExpiryForCreation(K key, SoftLock<V> softLock) { if (softLock.getTransactionId() != null) { // phase 1 prepare, create -> forever return ExpiryPolicy.INFINITE; } else { // phase 2 commit, or during a TX's lifetime, create -> some time Duration duration; try { duration = configuredExpiry.getExpiryForCreation(key, softLock.getOldValue()); } catch (RuntimeException re) { LOGGER.error("Expiry computation caused an exception - Expiry duration will be 0 ", re); return Duration.ZERO; } return duration; } }
} else { if (oldSoftLock.getOldValue() == null) { duration = configuredExpiry.getExpiryForCreation(key, oldSoftLock.getOldValue()); } catch (RuntimeException re) { LOGGER.error("Expiry computation caused an exception - Expiry duration will be 0 ", re);
SoftLock<V> softLock = softLockValueHolder.get(); if (isInDoubt(softLock)) { currentContext.addCommand(key, new StoreEvictCommand<>(softLock.getOldValue())); return RemoveStatus.KEY_MISSING; } else if (!softLock.getOldValue().equals(value)) { return RemoveStatus.KEY_PRESENT; } else { currentContext.addCommand(key, new StoreRemoveCommand<>(softLock.getOldValue())); return RemoveStatus.REMOVED;
@Override public ValueHolder<V> get(K key) throws StoreAccessException { checkKey(key); XATransactionContext<K, V> currentContext = getCurrentContext(); if (currentContext.removed(key)) { return null; } XAValueHolder<V> newValueHolder = currentContext.newValueHolderOf(key); if (newValueHolder != null) { return newValueHolder; } ValueHolder<SoftLock<V>> softLockValueHolder = getSoftLockValueHolderFromUnderlyingStore(key); if (softLockValueHolder == null) { return null; } SoftLock<V> softLock = softLockValueHolder.get(); if (isInDoubt(softLock)) { currentContext.addCommand(key, new StoreEvictCommand<>(softLock.getOldValue())); return null; } return new XAValueHolder<>(softLockValueHolder, softLock.getOldValue()); }
@Override public SoftLock<T> copyForRead(SoftLock<T> obj) { T oldValue = valueCopier.copyForRead(obj.getOldValue()); XAValueHolder<T> valueHolder = obj.getNewValueHolder(); XAValueHolder<T> newValueHolder = valueHolder == null ? null : new XAValueHolder<>(valueHolder, valueCopier.copyForRead(valueHolder .get())); return new SoftLock<>(obj.getTransactionId(), oldValue, newValueHolder); }
@Override public SoftLock<T> copyForWrite(SoftLock<T> obj) { T oldValue = valueCopier.copyForWrite(obj.getOldValue()); XAValueHolder<T> valueHolder = obj.getNewValueHolder(); XAValueHolder<T> newValueHolder = valueHolder == null ? null : new XAValueHolder<>(valueHolder, valueCopier.copyForWrite(valueHolder .get())); return new SoftLock<>(obj.getTransactionId(), oldValue, newValueHolder); }
@Override public boolean containsKey(K key) throws StoreAccessException { checkKey(key); if (getCurrentContext().touched(key)) { return getCurrentContext().newValueHolderOf(key) != null; } ValueHolder<SoftLock<V>> softLockValueHolder = getSoftLockValueHolderFromUnderlyingStore(key); return softLockValueHolder != null && softLockValueHolder.get().getTransactionId() == null && softLockValueHolder.get().getOldValue() != null; }
@Override public boolean remove(K key) throws StoreAccessException { checkKey(key); XATransactionContext<K, V> currentContext = getCurrentContext(); if (currentContext.touched(key)) { V oldValue = currentContext.oldValueOf(key); V newValue = currentContext.newValueOf(key); currentContext.addCommand(key, new StoreRemoveCommand<>(oldValue)); return newValue != null; } ValueHolder<SoftLock<V>> softLockValueHolder = getSoftLockValueHolderFromUnderlyingStore(key); boolean status = false; if (softLockValueHolder != null) { SoftLock<V> softLock = softLockValueHolder.get(); if (isInDoubt(softLock)) { currentContext.addCommand(key, new StoreEvictCommand<>(softLock.getOldValue())); } else { status = currentContext.addCommand(key, new StoreRemoveCommand<>(softLock.getOldValue())); } } return status; }
V oldValue = softLock == null ? null : softLock.getOldValue(); V newValue = mappingFunction.apply(key, oldValue); XAValueHolder<V> xaValueHolder = newValue == null ? null : new XAValueHolder<>(newValue, timeSource.getTimeMillis());
@Override public ValueHolder<V> putIfAbsent(K key, V value, Consumer<Boolean> put) throws StoreAccessException { checkKey(key); checkValue(value); XATransactionContext<K, V> currentContext = getCurrentContext(); if (currentContext.touched(key)) { V oldValue = currentContext.oldValueOf(key); V newValue = currentContext.newValueOf(key); if (newValue == null) { currentContext.addCommand(key, new StorePutCommand<>(oldValue, new XAValueHolder<>(value, timeSource.getTimeMillis()))); return null; } else { return currentContext.newValueHolderOf(key); } } ValueHolder<SoftLock<V>> softLockValueHolder = getSoftLockValueHolderFromUnderlyingStore(key); if (softLockValueHolder != null) { SoftLock<V> softLock = softLockValueHolder.get(); if (isInDoubt(softLock)) { currentContext.addCommand(key, new StoreEvictCommand<>(softLock.getOldValue())); return null; } else { return new XAValueHolder<>(softLockValueHolder, softLock.getOldValue()); } } else { currentContext.addCommand(key, new StorePutCommand<>(null, new XAValueHolder<>(value, timeSource.getTimeMillis()))); return null; } }
currentContext.addCommand(key, new StoreEvictCommand<>(softLockValueHolder.get().getOldValue())); xaValueHolder = new XAValueHolder<>(softLockValueHolder, softLockValueHolder.get().getNewValueHolder().get()); } else { xaValueHolder = currentContext.newValueHolderOf(key); } else { xaValueHolder = new XAValueHolder<>(softLockValueHolder, softLockValueHolder.get().getOldValue());
@Override public PutStatus put(K key, V value) throws StoreAccessException { checkKey(key); checkValue(value); XATransactionContext<K, V> currentContext = getCurrentContext(); if (currentContext.touched(key)) { V oldValue = currentContext.oldValueOf(key); currentContext.addCommand(key, new StorePutCommand<>(oldValue, new XAValueHolder<>(value, timeSource.getTimeMillis()))); return PutStatus.PUT; } ValueHolder<SoftLock<V>> softLockValueHolder = getSoftLockValueHolderFromUnderlyingStore(key); if (softLockValueHolder != null) { SoftLock<V> softLock = softLockValueHolder.get(); if (isInDoubt(softLock)) { currentContext.addCommand(key, new StoreEvictCommand<>(softLock.getOldValue())); } else { if (currentContext.addCommand(key, new StorePutCommand<>(softLock.getOldValue(), new XAValueHolder<>(value, timeSource .getTimeMillis())))) { return PutStatus.PUT; } } } else { if (currentContext.addCommand(key, new StorePutCommand<>(null, new XAValueHolder<>(value, timeSource.getTimeMillis())))) { return PutStatus.PUT; } } return PutStatus.NOOP; }
if (softLockValueHolder != null) { SoftLock<V> softLock = softLockValueHolder.get(); V previousValue = softLock.getOldValue(); if (isInDoubt(softLock)) { currentContext.addCommand(key, new StoreEvictCommand<>(previousValue));
SoftLock<V> softLock = softLockValueHolder.get(); if (isInDoubt(softLock)) { currentContext.addCommand(key, new StoreEvictCommand<>(softLock.getOldValue())); return null; } else { V oldValue = softLock.getOldValue(); currentContext.addCommand(key, new StorePutCommand<>(oldValue, new XAValueHolder<>(value, timeSource.getTimeMillis()))); return new XAValueHolder<>(oldValue, softLockValueHolder.creationTime());