use of io.pravega.segmentstore.storage.LogAddress in project pravega by pravega.
the class BookKeeperLog method append.
@Override
public CompletableFuture<LogAddress> append(ArrayView data, Duration timeout) {
ensurePreconditions();
long traceId = LoggerHelpers.traceEnterWithContext(log, this.traceObjectId, "append", data.getLength());
if (data.getLength() > getMaxAppendLength()) {
return Futures.failedFuture(new WriteTooLongException(data.getLength(), getMaxAppendLength()));
}
Timer timer = new Timer();
// Queue up the write.
CompletableFuture<LogAddress> result = new CompletableFuture<>();
this.writes.add(new Write(data, getWriteLedger(), result));
// Trigger Write Processor.
this.writeProcessor.runAsync();
// Post append tasks. We do not need to wait for these to happen before returning the call.
result.whenCompleteAsync((address, ex) -> {
if (ex != null) {
handleWriteException(ex);
} else {
// Update metrics and take care of other logging tasks.
this.metrics.writeCompleted(timer.getElapsed());
LoggerHelpers.traceLeave(log, this.traceObjectId, "append", traceId, data.getLength(), address);
}
}, this.executorService);
return result;
}
use of io.pravega.segmentstore.storage.LogAddress in project pravega by pravega.
the class RecoveryProcessor method recordTruncationMarker.
private void recordTruncationMarker(DataFrameRecord<Operation> dataFrameRecord) {
// Truncation Markers are stored directly in the ContainerMetadata. There is no need for an OperationMetadataUpdater
// to do this.
// Determine and record Truncation Markers, but only if the current operation spans multiple DataFrames
// or it's the last entry in a DataFrame.
LogAddress lastFullAddress = dataFrameRecord.getLastFullDataFrameAddress();
LogAddress lastUsedAddress = dataFrameRecord.getLastUsedDataFrameAddress();
if (lastFullAddress != null && lastFullAddress.getSequence() != lastUsedAddress.getSequence()) {
// This operation spans multiple DataFrames. The TruncationMarker should be set on the last DataFrame
// that ends with a part of it.
this.metadata.recordTruncationMarker(dataFrameRecord.getItem().getSequenceNumber(), lastFullAddress);
} else if (dataFrameRecord.isLastFrameEntry()) {
// The operation was the last one in the frame. This is a Truncation Marker.
this.metadata.recordTruncationMarker(dataFrameRecord.getItem().getSequenceNumber(), lastUsedAddress);
}
}
use of io.pravega.segmentstore.storage.LogAddress in project pravega by pravega.
the class StreamSegmentContainerMetadataTests method testReset.
/**
* Tests the ability for the metadata to reset itself.
*/
@Test
public void testReset() {
// Segments, Sequence Number + Truncation markers
final UpdateableContainerMetadata m = new MetadataBuilder(CONTAINER_ID).build();
// Set a high Sequence Number
m.enterRecoveryMode();
m.setOperationSequenceNumber(Integer.MAX_VALUE);
m.setContainerEpoch(Integer.MAX_VALUE + 1L);
m.exitRecoveryMode();
// Populate some StreamSegments.
ArrayList<Long> segmentIds = new ArrayList<>();
for (long i = 0; i < SEGMENT_COUNT; i++) {
final long segmentId = segmentIds.size();
segmentIds.add(segmentId);
m.mapStreamSegmentId(getName(segmentId), segmentId);
for (long j = 0; j < TRANSACTIONS_PER_SEGMENT_COUNT; j++) {
final long transactionId = segmentIds.size();
segmentIds.add(transactionId);
m.mapStreamSegmentId(getName(transactionId), transactionId, segmentId);
}
}
// Add some truncation markers.
final long truncationMarkerSeqNo = 10;
m.recordTruncationMarker(truncationMarkerSeqNo, new TestLogAddress(truncationMarkerSeqNo));
m.setValidTruncationPoint(truncationMarkerSeqNo);
AssertExtensions.assertThrows("reset() worked in non-recovery mode.", m::reset, ex -> ex instanceof IllegalStateException);
// Do the reset.
m.enterRecoveryMode();
m.reset();
m.exitRecoveryMode();
// Verify everything was reset.
Assert.assertEquals("Sequence Number was not reset.", ContainerMetadata.INITIAL_OPERATION_SEQUENCE_NUMBER, m.getOperationSequenceNumber());
AssertExtensions.assertLessThan("Epoch was not reset.", 0, m.getContainerEpoch());
for (long segmentId : segmentIds) {
Assert.assertEquals("SegmentMetadata was not reset (getStreamSegmentId).", ContainerMetadata.NO_STREAM_SEGMENT_ID, m.getStreamSegmentId(getName(segmentId), false));
Assert.assertNull("SegmentMetadata was not reset (getStreamSegmentMetadata).", m.getStreamSegmentMetadata(segmentId));
}
LogAddress tmSeqNo = m.getClosestTruncationMarker(truncationMarkerSeqNo);
Assert.assertNull("Truncation Markers were not reset.", tmSeqNo);
Assert.assertFalse("Truncation Points were not reset.", m.isValidTruncationPoint(truncationMarkerSeqNo));
}
use of io.pravega.segmentstore.storage.LogAddress in project pravega by pravega.
the class StreamSegmentContainerMetadata method recordTruncationMarker.
// endregion
// region TruncationMarkerRepository Implementation
@Override
public void recordTruncationMarker(long operationSequenceNumber, LogAddress address) {
Exceptions.checkArgument(operationSequenceNumber >= 0, "operationSequenceNumber", "Operation Sequence Number must be a positive number.");
Preconditions.checkNotNull(address, "address");
synchronized (this.truncationMarkers) {
LogAddress existing = this.truncationMarkers.getOrDefault(operationSequenceNumber, null);
if (existing == null || existing.getSequence() < address.getSequence()) {
this.truncationMarkers.put(operationSequenceNumber, address);
}
}
}
use of io.pravega.segmentstore.storage.LogAddress in project pravega by pravega.
the class DataFrameInputStream method setCurrentFrameEntry.
private void setCurrentFrameEntry(DataFrame.DataFrameEntry nextEntry) throws IOException {
long dataFrameSequence = nextEntry.getFrameAddress().getSequence();
LogAddress lastUsedAddress = this.currentRecordBuilder.getLastUsedDataFrameAddress();
if (lastUsedAddress != null && dataFrameSequence < lastUsedAddress.getSequence()) {
throw new SerializationException(String.format("Invalid DataFrameSequence. Expected at least '%d', found '%d'.", lastUsedAddress.getSequence(), dataFrameSequence));
}
if (nextEntry.isLastEntryInDataFrame()) {
// This is the last segment in this DataFrame, so we need to set the lastFullDataFrameAddress to the right value.
this.currentRecordBuilder.lastFullDataFrameAddress(nextEntry.getFrameAddress());
}
this.currentRecordBuilder.lastUsedDataFrameAddress(nextEntry.getFrameAddress());
this.currentRecordBuilder.lastFrameEntry(nextEntry.isLastEntryInDataFrame());
this.currentEntry = nextEntry;
if (this.currentEntry.isLastRecordEntry()) {
this.hasReadAnyData = true;
}
this.currentRecordBuilder.withEntry(nextEntry.getFrameAddress(), nextEntry.getFrameOffset(), nextEntry.getLength(), nextEntry.isLastEntryInDataFrame());
}
Aggregations