@SuppressWarnings("OptionalUsedAsFieldOrParameterType") // Passed from other operations returning Optional private SequenceAndBound determineNewSequenceAndBound( Optional<SequenceAndBound> coordinationValue, ValueAndBound<T> extantValueAndBound, T targetValue) { long sequenceNumber; long newBound; if (shouldReuseExtantValue(coordinationValue, extantValueAndBound.value(), targetValue)) { // Safe as we're only on this branch if the value is present sequenceNumber = coordinationValue.get().sequence(); newBound = getNewBound(sequenceNumberSupplier.getAsLong()); } else { sequenceNumber = sequenceNumberSupplier.getAsLong(); putUnlessValueExists(sequenceNumber, targetValue); newBound = getNewBound(sequenceNumber); } return SequenceAndBound.of(sequenceNumber, newBound); }
private CheckAndSetResult<ValueAndBound<T>> extractRelevantValues(T targetValue, long newBound, CheckAndSetResult<SequenceAndBound> casResult) { if (casResult.successful()) { return CheckAndSetResult.of(true, ImmutableList.of(ValueAndBound.of(Optional.of(targetValue), newBound))); } return CheckAndSetResult.of( false, casResult.existingValues() .stream() .map(value -> ValueAndBound.of(getValue(value.sequence()), value.bound())) .collect(Collectors.toList())); }
@SuppressWarnings("OptionalUsedAsFieldOrParameterType") // Passed from other operations returning Optional private SequenceAndBound determineNewSequenceAndBound( Optional<SequenceAndBound> coordinationValue, ValueAndBound<T> extantValueAndBound, T targetValue) { long sequenceNumber; long newBound; if (shouldReuseExtantValue(coordinationValue, extantValueAndBound.value(), targetValue)) { // Safe as we're only on this branch if the value is present sequenceNumber = coordinationValue.get().sequence(); newBound = getNewBound(sequenceNumberSupplier.getAsLong()); } else { sequenceNumber = sequenceNumberSupplier.getAsLong(); putUnlessValueExists(sequenceNumber, targetValue); newBound = getNewBound(sequenceNumber); } return SequenceAndBound.of(sequenceNumber, newBound); }
@Override public CheckAndSetResult<ValueAndBound<T>> transformAgreedValue(Function<ValueAndBound<T>, T> transform) { Optional<SequenceAndBound> coordinationValue = getCoordinationValue(); ValueAndBound<T> extantValueAndBound = ValueAndBound.of(coordinationValue.flatMap( sequenceAndBound -> getValue(sequenceAndBound.sequence())), coordinationValue.map(SequenceAndBound::bound).orElse(SequenceAndBound.INVALID_BOUND)); T targetValue = transform.apply(extantValueAndBound); SequenceAndBound newSequenceAndBound = determineNewSequenceAndBound(coordinationValue, extantValueAndBound, targetValue); CheckAndSetResult<SequenceAndBound> casResult = checkAndSetCoordinationValue( coordinationValue, newSequenceAndBound); return extractRelevantValues(targetValue, newSequenceAndBound.bound(), casResult); }
@Test public void valuePreservingTransformationsDoNotWriteTheSameValueAgain() { coordinationStore.transformAgreedValue(unused -> VALUE_1); SequenceAndBound firstSequenceAndBound = coordinationStore.getCoordinationValue().get(); coordinationStore.transformAgreedValue(VALUE_PRESERVING_FUNCTION); SequenceAndBound secondSequenceAndBound = coordinationStore.getCoordinationValue().get(); assertThat(firstSequenceAndBound.sequence()).isEqualTo(secondSequenceAndBound.sequence()); assertThat(firstSequenceAndBound.bound()).isLessThan(secondSequenceAndBound.bound()); }
private CheckAndSetResult<ValueAndBound<T>> extractRelevantValues(T targetValue, long newBound, CheckAndSetResult<SequenceAndBound> casResult) { if (casResult.successful()) { return CheckAndSetResult.of(true, ImmutableList.of(ValueAndBound.of(Optional.of(targetValue), newBound))); } return CheckAndSetResult.of( false, casResult.existingValues() .stream() .map(value -> ValueAndBound.of(getValue(value.sequence()), value.bound())) .collect(Collectors.toList())); }
@Override public CheckAndSetResult<ValueAndBound<T>> transformAgreedValue(Function<ValueAndBound<T>, T> transform) { Optional<SequenceAndBound> coordinationValue = getCoordinationValue(); ValueAndBound<T> extantValueAndBound = ValueAndBound.of(coordinationValue.flatMap( sequenceAndBound -> getValue(sequenceAndBound.sequence())), coordinationValue.map(SequenceAndBound::bound).orElse(SequenceAndBound.INVALID_BOUND)); T targetValue = transform.apply(extantValueAndBound); SequenceAndBound newSequenceAndBound = determineNewSequenceAndBound(coordinationValue, extantValueAndBound, targetValue); CheckAndSetResult<SequenceAndBound> casResult = checkAndSetCoordinationValue( coordinationValue, newSequenceAndBound); return extractRelevantValues(targetValue, newSequenceAndBound.bound(), casResult); }