private TimestampPartitioningMap<Integer> installNewVersionInMap( TimestampPartitioningMap<Integer> sourceMap, long bound, int newVersion) { return sourceMap.copyInstallingNewValue(bound, newVersion); }
static ImmutableInternalSchemaMetadata.Builder builder() { return ImmutableInternalSchemaMetadata.builder(); }
public TimestampPartitioningMap<T> copyInstallingNewValue( long lowerBoundForNewVersion, T newValue) { RangeAndValue<T> latestEntry = getLatestEntry(); validateProvidedTimestampBounds(lowerBoundForNewVersion, newValue, latestEntry); ImmutableRangeMap.Builder<Long, T> builder = ImmutableRangeMap.builder(); copyOldRangesFromPreviousMap(latestEntry, builder); addNewRanges(lowerBoundForNewVersion, newValue, latestEntry, builder); return ImmutableTimestampPartitioningMap.of(builder.build()); }
private void copyOldRangesFromPreviousMap( RangeAndValue latestRangeAndValue, @Output ImmutableRangeMap.Builder<Long, T> builder) { timestampMappings() .stream() .filter(rangeAndValue -> !rangeAndValue.equals(latestRangeAndValue)) .forEach(rangeAndValue -> builder.put(rangeAndValue.longRange(), rangeAndValue.value())); }
@Test public void canSwitchBetweenSchemaVersions() { assertThat(manager.tryInstallNewTransactionsSchemaVersion(2)).isTrue(); fastForwardTimestampByOneHundredMillion(); assertThat(manager.getTransactionsSchemaVersion(timestamps.getFreshTimestamp())).isEqualTo(2); assertThat(manager.tryInstallNewTransactionsSchemaVersion(1)).isTrue(); fastForwardTimestampByOneHundredMillion(); assertThat(manager.getTransactionsSchemaVersion(timestamps.getFreshTimestamp())).isEqualTo(1); }
@Value.Check public void check() { validateCoversPreciselyAllTimestamps(rangeMapView()); }
private RangeAndValue<T> getLatestEntry() { return RangeAndValue.fromMapEntry(rangeMapView() .asDescendingMapOfRanges() .entrySet() .iterator() .next()); }
@Override public void forceInstallNewTransactionsSchemaVersion(int newVersion) { while (transactionSchemaManager.getTransactionsSchemaVersion( timestampService.getFreshTimestamp()) != newVersion) { transactionSchemaManager.tryInstallNewTransactionsSchemaVersion(newVersion); advanceOneHundredMillionTimestamps(); } }
private static Optional<Integer> extractTimestampVersion( Optional<ValueAndBound<InternalSchemaMetadata>> valueAndBound, long timestamp) { return valueAndBound .flatMap(ValueAndBound::value) .map(InternalSchemaMetadata::timestampToTransactionsTableSchemaVersion) .map(versionMap -> versionMap.getValueForTimestamp(timestamp)); } }
@Test public void canFailToInstallNewVersions() { TransactionSchemaManager newManager = createTransactionSchemaManager(new InMemoryTimestampService()); // Always need to seed the default value, if it's not there assertThat(newManager.tryInstallNewTransactionsSchemaVersion(5)).isFalse(); assertThat(newManager.tryInstallNewTransactionsSchemaVersion(5)).isTrue(); }
@Override public boolean tryInstallNewTransactionsSchemaVersion(int newVersion) { return transactionSchemaManager.tryInstallNewTransactionsSchemaVersion(newVersion); }
@Override public int getTransactionsSchemaVersion(long timestamp) { return transactionSchemaManager.getTransactionsSchemaVersion(timestamp); }
static <T> RangeAndValue<T> of(Range<Long> longRange, T value) { return ImmutableRangeAndValue.of(longRange, value); }
static <T> RangeAndValue<T> fromMapEntry(Map.Entry<Range<Long>, T> entry) { return of(entry.getKey(), entry.getValue()); } }
public T getValueForTimestamp(long timestamp) { return rangeMapView().get(timestamp); }
@Value.Lazy RangeMap<Long, T> rangeMapView() { ImmutableRangeMap.Builder<Long, T> builder = new ImmutableRangeMap.Builder<>(); timestampMappings() .forEach(rangeAndValue -> builder.put(rangeAndValue.longRange(), rangeAndValue.value())); return builder.build(); }
@Test public void newSchemaVersionsCanBeInstalledWithinOneHundredMillionTimestamps() { assertThat(manager.tryInstallNewTransactionsSchemaVersion(2)).isTrue(); fastForwardTimestampByOneHundredMillion(); assertThat(manager.getTransactionsSchemaVersion(timestamps.getFreshTimestamp())).isEqualTo(2); }
private static Optional<Integer> extractTimestampVersion( Optional<ValueAndBound<InternalSchemaMetadata>> valueAndBound, long timestamp) { return valueAndBound .flatMap(ValueAndBound::value) .map(InternalSchemaMetadata::timestampToTransactionsTableSchemaVersion) .map(versionMap -> versionMap.getValueForTimestamp(timestamp)); } }