use of io.pravega.controller.store.stream.records.HistoryTimeSeriesRecord in project pravega by pravega.
the class PersistentStreamBase method rollingTxnCreateDuplicateEpochs.
@Override
public CompletableFuture<Void> rollingTxnCreateDuplicateEpochs(Map<Long, Long> sealedTxnEpochSegments, long time, VersionedMetadata<CommittingTransactionsRecord> record, OperationContext context) {
Preconditions.checkNotNull(context, "Operation context cannot be null");
Preconditions.checkArgument(record.getObject().isRollingTxnRecord());
CommittingTransactionsRecord committingTxnRecord = record.getObject();
return getActiveEpoch(true, context).thenCompose(activeEpochRecord -> getEpochRecord(committingTxnRecord.getEpoch(), context).thenCompose(transactionEpochRecord -> {
if (activeEpochRecord.getEpoch() > committingTxnRecord.getCurrentEpoch()) {
log.debug(context.getRequestId(), "Duplicate Epochs {} already created. Ignore.", committingTxnRecord.getNewActiveEpoch());
return CompletableFuture.completedFuture(null);
}
long timeStamp = Math.max(activeEpochRecord.getCreationTime() + 1, time);
ImmutableList.Builder<StreamSegmentRecord> duplicateTxnSegmentsBuilder = ImmutableList.builder();
transactionEpochRecord.getSegments().stream().forEach(x -> duplicateTxnSegmentsBuilder.add(newSegmentRecord(computeSegmentId(getSegmentNumber(x.segmentId()), committingTxnRecord.getNewTxnEpoch()), timeStamp, x.getKeyStart(), x.getKeyEnd())));
ImmutableList.Builder<StreamSegmentRecord> duplicateActiveSegmentsBuilder = ImmutableList.builder();
activeEpochRecord.getSegments().stream().forEach(x -> duplicateActiveSegmentsBuilder.add(newSegmentRecord(computeSegmentId(getSegmentNumber(x.segmentId()), committingTxnRecord.getNewActiveEpoch()), timeStamp + 1, x.getKeyStart(), x.getKeyEnd())));
CompletableFuture<EpochRecord> txnEpochFuture = getSplitMergeCountsTillEpoch(activeEpochRecord, context).thenCompose(txnSplitMergeCount -> {
ImmutableList<StreamSegmentRecord> duplicateTxnEpochSegments = duplicateTxnSegmentsBuilder.build();
EpochRecord duplicateTxnEpoch = new EpochRecord(committingTxnRecord.getNewTxnEpoch(), transactionEpochRecord.getReferenceEpoch(), duplicateTxnEpochSegments, timeStamp, getNewEpochSplitCount(txnSplitMergeCount.getKey(), activeEpochRecord.getSegments(), duplicateTxnEpochSegments), getNewEpochMergeCount(txnSplitMergeCount.getValue(), activeEpochRecord.getSegments(), duplicateTxnEpochSegments));
return CompletableFuture.completedFuture(duplicateTxnEpoch);
});
CompletableFuture<EpochRecord> activeEpochFuture = txnEpochFuture.thenCompose(previousEpoch -> getSplitMergeCountsTillEpoch(previousEpoch, context).thenCompose(prevSplitMergeCounts -> {
ImmutableList<StreamSegmentRecord> activeEpochSegments = duplicateActiveSegmentsBuilder.build();
EpochRecord duplicateActiveEpoch = new EpochRecord(committingTxnRecord.getNewActiveEpoch(), activeEpochRecord.getReferenceEpoch(), activeEpochSegments, timeStamp + 1, getNewEpochSplitCount(prevSplitMergeCounts.getKey(), previousEpoch.getSegments(), activeEpochSegments), getNewEpochMergeCount(prevSplitMergeCounts.getValue(), previousEpoch.getSegments(), activeEpochSegments));
return CompletableFuture.completedFuture(duplicateActiveEpoch);
}));
return CompletableFuture.allOf(txnEpochFuture, activeEpochFuture).thenCompose(v -> {
EpochRecord duplicateTxnEpoch = txnEpochFuture.join();
EpochRecord duplicateActiveEpoch = activeEpochFuture.join();
HistoryTimeSeriesRecord timeSeriesRecordTxnEpoch = new HistoryTimeSeriesRecord(duplicateTxnEpoch.getEpoch(), duplicateTxnEpoch.getReferenceEpoch(), ImmutableList.of(), ImmutableList.of(), timeStamp);
HistoryTimeSeriesRecord timeSeriesRecordActiveEpoch = new HistoryTimeSeriesRecord(duplicateActiveEpoch.getEpoch(), duplicateActiveEpoch.getReferenceEpoch(), ImmutableList.of(), ImmutableList.of(), timeStamp + 1);
return createEpochRecord(duplicateTxnEpoch, context).thenCompose(x -> updateHistoryTimeSeries(timeSeriesRecordTxnEpoch, context)).thenCompose(x -> createEpochRecord(duplicateActiveEpoch, context)).thenCompose(x -> updateHistoryTimeSeries(timeSeriesRecordActiveEpoch, context)).thenCompose(x -> createSegmentSealedEpochRecords(activeEpochRecord.getSegments().stream().map(StreamSegmentRecord::segmentId).collect(Collectors.toList()), duplicateTxnEpoch.getEpoch(), context)).thenCompose(x -> createSegmentSealedEpochRecords(duplicateTxnEpoch.getSegments().stream().map(StreamSegmentRecord::segmentId).collect(Collectors.toList()), duplicateActiveEpoch.getEpoch(), context));
}).thenCompose(r -> updateSealedSegmentSizes(sealedTxnEpochSegments, context));
}));
}
use of io.pravega.controller.store.stream.records.HistoryTimeSeriesRecord in project pravega by pravega.
the class ControllerMetadataJsonSerializerTest method testHistoryTimeSeries.
@Test
public void testHistoryTimeSeries() {
List<StreamSegmentRecord> sealedSegments = Lists.newArrayList(StreamSegmentRecord.newSegmentRecord(0, 0, 0L, 0.0, 1.0));
List<StreamSegmentRecord> newSegments = Lists.newArrayList(StreamSegmentRecord.newSegmentRecord(0, 0, 0L, 0.0, 1.0), StreamSegmentRecord.newSegmentRecord(1, 1, 0L, 0.1, 0.2));
HistoryTimeSeriesRecord node = new HistoryTimeSeriesRecord(0, 0, ImmutableList.copyOf(sealedSegments), ImmutableList.copyOf(newSegments), 0L);
HistoryTimeSeriesRecord node2 = new HistoryTimeSeriesRecord(1, 0, ImmutableList.of(), ImmutableList.of(), 1L);
HistoryTimeSeriesRecord node3 = new HistoryTimeSeriesRecord(4, 4, ImmutableList.copyOf(sealedSegments), ImmutableList.copyOf(newSegments), 1L);
HistoryTimeSeries record = new HistoryTimeSeries(ImmutableList.of(node, node2, node3));
testRecordSerialization(record, HistoryTimeSeries.class);
}
use of io.pravega.controller.store.stream.records.HistoryTimeSeriesRecord in project pravega by pravega.
the class PersistentStreamBase method scaleCreateNewEpoch.
@Override
public CompletableFuture<VersionedMetadata<EpochTransitionRecord>> scaleCreateNewEpoch(VersionedMetadata<EpochTransitionRecord> versionedMetadata, OperationContext context) {
Preconditions.checkNotNull(context, "Operation context cannot be null");
return getActiveEpochRecord(true, context).thenCompose(currentEpoch -> {
// only perform idempotent update. If update is already completed, do nothing.
if (currentEpoch.getEpoch() < versionedMetadata.getObject().getNewEpoch()) {
EpochTransitionRecord epochTransition = versionedMetadata.getObject();
// time
long time = Math.max(epochTransition.getTime(), currentEpoch.getCreationTime() + 1);
// new segments
ImmutableList.Builder<StreamSegmentRecord> newSegmentsBuilder = ImmutableList.builder();
epochTransition.getNewSegmentsWithRange().forEach((key, value) -> newSegmentsBuilder.add(newSegmentRecord(key, time, value.getKey(), value.getValue())));
// sealed segments
ImmutableList.Builder<StreamSegmentRecord> sealedSegmentsBuilder = ImmutableList.builder();
epochTransition.getSegmentsToSeal().forEach(x -> sealedSegmentsBuilder.add(currentEpoch.getSegment(x)));
// overall segments in epoch
ImmutableList.Builder<StreamSegmentRecord> builder = ImmutableList.builder();
currentEpoch.getSegments().forEach(x -> {
if (!epochTransition.getSegmentsToSeal().contains(x.segmentId())) {
builder.add(x);
}
});
ImmutableList<StreamSegmentRecord> newSegments = newSegmentsBuilder.build();
builder.addAll(newSegments);
ImmutableList<StreamSegmentRecord> newEpochSegments = builder.build();
// epoch record
return getSplitMergeCountsTillEpoch(currentEpoch, context).thenCompose(cumulativeSplitMergeCount -> {
EpochRecord epochRecord = new EpochRecord(epochTransition.getNewEpoch(), epochTransition.getNewEpoch(), newEpochSegments, time, getNewEpochSplitCount(cumulativeSplitMergeCount.getKey(), currentEpoch.getSegments(), newEpochSegments), getNewEpochMergeCount(cumulativeSplitMergeCount.getValue(), currentEpoch.getSegments(), newEpochSegments));
HistoryTimeSeriesRecord timeSeriesRecord = new HistoryTimeSeriesRecord(epochTransition.getNewEpoch(), epochTransition.getNewEpoch(), sealedSegmentsBuilder.build(), newSegments, epochRecord.getCreationTime());
return createEpochRecord(epochRecord, context).thenCompose(x -> updateHistoryTimeSeries(timeSeriesRecord, context)).thenCompose(x -> createSegmentSealedEpochRecords(epochTransition.getSegmentsToSeal(), epochTransition.getNewEpoch(), context)).thenApply(x -> versionedMetadata);
});
} else {
return CompletableFuture.completedFuture(versionedMetadata);
}
});
}
use of io.pravega.controller.store.stream.records.HistoryTimeSeriesRecord in project pravega by pravega.
the class PersistentStreamBase method createHistoryTimeSeriesChunk.
private CompletableFuture<Void> createHistoryTimeSeriesChunk(int chunkNumber, HistoryTimeSeriesRecord epoch, OperationContext context) {
ImmutableList.Builder<HistoryTimeSeriesRecord> builder = ImmutableList.builder();
HistoryTimeSeries timeSeries = new HistoryTimeSeries(builder.add(epoch).build());
return createHistoryTimeSeriesChunkDataIfAbsent(chunkNumber, timeSeries, context);
}
Aggregations