use of io.pravega.controller.store.stream.records.StreamSegmentRecord in project pravega by pravega.
the class ControllerMetadataJsonSerializerTest method testStreamTruncationRecord.
@Test
public void testStreamTruncationRecord() {
Map<StreamSegmentRecord, Integer> span = new HashMap<>();
span.put(StreamSegmentRecord.newSegmentRecord(0, 0, 0L, 0.0, 1.0), 0);
span.put(StreamSegmentRecord.newSegmentRecord(1, 0, 0L, 0.0, 1.0), 0);
Map<Long, Long> streamCut = new HashMap<>();
streamCut.put(0L, 0L);
Set<Long> set = new HashSet<>();
set.add(0L);
StreamTruncationRecord record = new StreamTruncationRecord(ImmutableMap.copyOf(streamCut), ImmutableMap.copyOf(span), ImmutableSet.copyOf(set), ImmutableSet.copyOf(set), 0L, true);
testRecordSerialization(record, StreamTruncationRecord.class);
}
use of io.pravega.controller.store.stream.records.StreamSegmentRecord in project pravega by pravega.
the class ControllerService method createTransaction.
/**
* Creates transaction where a new txn id is generated and the txn segments and metadata is created.
*
* @param scope scope
* @param stream stream name
* @param lease lease for transaction.
* @param requestId request id
* @return Transaction state future
*/
@SuppressWarnings("ReturnCount")
public CompletableFuture<Pair<UUID, List<SegmentRange>>> createTransaction(final String scope, final String stream, final long lease, final long requestId) {
Exceptions.checkNotNullOrEmpty(scope, "scope");
Exceptions.checkNotNullOrEmpty(stream, "stream");
Timer timer = new Timer();
OperationContext context = streamStore.createStreamContext(scope, stream, requestId);
return streamStore.getConfiguration(scope, stream, context, executor).thenCompose(streamConfig -> streamTransactionMetadataTasks.createTxn(scope, stream, lease, requestId, streamConfig.getRolloverSizeBytes())).thenApply(pair -> {
VersionedTransactionData data = pair.getKey();
List<StreamSegmentRecord> segments = pair.getValue();
return new ImmutablePair<>(data.getId(), getSegmentRanges(segments, scope, stream));
}).handle((result, ex) -> {
if (ex != null) {
TransactionMetrics.getInstance().createTransactionFailed(scope, stream);
throw new CompletionException(ex);
}
TransactionMetrics.getInstance().createTransaction(scope, stream, timer.getElapsed());
return result;
});
}
use of io.pravega.controller.store.stream.records.StreamSegmentRecord in project pravega by pravega.
the class PersistentStreamBase method createHistoryRecords.
private CompletionStage<Void> createHistoryRecords(int startingSegmentNumber, CreateStreamResponse createStreamResponse, OperationContext context) {
Preconditions.checkNotNull(context, "operation context cannot be null");
final int numSegments = createStreamResponse.getConfiguration().getScalingPolicy().getMinNumSegments();
// create epoch 0 record
final double keyRangeChunk = 1.0 / numSegments;
long creationTime = createStreamResponse.getTimestamp();
final ImmutableList.Builder<StreamSegmentRecord> builder = ImmutableList.builder();
IntStream.range(0, numSegments).boxed().forEach(x -> builder.add(newSegmentRecord(0, startingSegmentNumber + x, creationTime, x * keyRangeChunk, (x + 1) * keyRangeChunk)));
EpochRecord epoch0 = new EpochRecord(0, 0, builder.build(), creationTime, 0L, 0L);
return createEpochRecord(epoch0, context).thenCompose(r -> createHistoryChunk(epoch0, context)).thenCompose(r -> createSealedSegmentSizeMapShardIfAbsent(0, context)).thenCompose(r -> createRetentionSetDataIfAbsent(new RetentionSet(ImmutableList.of()), context)).thenCompose(r -> createCurrentEpochRecordDataIfAbsent(epoch0, context));
}
use of io.pravega.controller.store.stream.records.StreamSegmentRecord in project pravega by pravega.
the class PersistentStreamBase method computeTruncationRecord.
private CompletableFuture<StreamTruncationRecord> computeTruncationRecord(StreamTruncationRecord previous, Map<Long, Long> streamCut, ImmutableMap<StreamSegmentRecord, Integer> span, OperationContext context) {
log.debug(context.getRequestId(), "computing truncation for stream {}/{}", scope, name);
// find segments between "previous" stream cut and current stream cut. these are segments to delete.
// Note: exclude segments in current streamcut
CompletableFuture<Map<StreamSegmentRecord, Integer>> previousSpanFuture = previous.getSpan().isEmpty() ? getEpochRecord(0, context).thenApply(epoch -> convertToSpan(epoch)) : CompletableFuture.completedFuture(previous.getSpan());
return previousSpanFuture.thenCompose(spanFrom -> segmentsBetweenStreamCutSpans(spanFrom, span, context)).thenCompose(segmentsBetween -> sizeBetweenStreamCuts(previous.getStreamCut(), streamCut, segmentsBetween, context).thenApply(sizeBetween -> {
ImmutableSet.Builder<Long> builder = ImmutableSet.builder();
segmentsBetween.stream().map(StreamSegmentRecord::segmentId).filter(x -> !streamCut.containsKey(x)).forEach(builder::add);
return new StreamTruncationRecord(ImmutableMap.copyOf(streamCut), span, previous.getDeletedSegments(), builder.build(), previous.getSizeTill() + sizeBetween, true);
}));
}
use of io.pravega.controller.store.stream.records.StreamSegmentRecord in project pravega by pravega.
the class PersistentStreamBase method startTruncation.
@Override
public CompletableFuture<Void> startTruncation(final Map<Long, Long> streamCut, OperationContext context) {
Preconditions.checkNotNull(context, "operation context cannot be null");
return getTruncationRecord(context).thenCompose(existing -> {
Preconditions.checkNotNull(existing);
Preconditions.checkArgument(!existing.getObject().isUpdating());
long mostRecent = getMostRecent(streamCut);
long oldest = getOldest(streamCut);
int epochLow = NameUtils.getEpoch(oldest);
int epochHigh = NameUtils.getEpoch(mostRecent);
return fetchEpochs(epochLow, epochHigh, true, context).thenCompose(epochs -> {
boolean isValid = isStreamCutValidInternal(streamCut, epochLow, epochs);
Exceptions.checkArgument(isValid, "streamCut", "invalid stream cut");
ImmutableMap<StreamSegmentRecord, Integer> span = computeStreamCutSpanInternal(streamCut, epochLow, epochHigh, epochs);
StreamTruncationRecord previous = existing.getObject();
// check greater than
Exceptions.checkArgument(streamCutEqualOrAfter(streamCut, span, previous.getStreamCut(), previous.getSpan()), "StreamCut", "Supplied streamcut is behind previous truncation point");
return computeTruncationRecord(previous, streamCut, span, context).thenCompose(prop -> Futures.toVoid(setTruncationData(new VersionedMetadata<>(prop, existing.getVersion()), context)));
});
});
}
Aggregations