use of io.pravega.segmentstore.server.SegmentMetadata in project pravega by pravega.
the class ContainerMetadataUpdateTransactionTests method assertMetadataSame.
/**
* Verify that the given ContainerMetadata objects contain the same data.
*/
static void assertMetadataSame(String message, ContainerMetadata expected, ContainerMetadata actual) {
Assert.assertEquals("Unexpected ContainerId.", expected.getContainerId(), actual.getContainerId());
Collection<Long> expectedSegmentIds = expected.getAllStreamSegmentIds();
Collection<Long> actualSegmentIds = actual.getAllStreamSegmentIds();
AssertExtensions.assertContainsSameElements(message + " Unexpected Segments mapped.", expectedSegmentIds, actualSegmentIds);
for (long streamSegmentId : expectedSegmentIds) {
SegmentMetadata expectedSegmentMetadata = expected.getStreamSegmentMetadata(streamSegmentId);
SegmentMetadata actualSegmentMetadata = actual.getStreamSegmentMetadata(streamSegmentId);
Assert.assertNotNull(message + " No metadata for Segment " + streamSegmentId, actualSegmentMetadata);
SegmentMetadataComparer.assertEquals(message, expectedSegmentMetadata, actualSegmentMetadata);
}
}
use of io.pravega.segmentstore.server.SegmentMetadata in project pravega by pravega.
the class ContainerMetadataUpdateTransactionTests method testRollback.
/**
* Tests the ability of the ContainerMetadataUpdateTransaction to rollback all outstanding changes.
*/
@Test
public void testRollback() throws Exception {
// Create a couple of operations, commit them, and then create a few more appends, merge a Transaction and seal
// the target Segment.
// Then call rollback(); verify no changes have been applied after the call to commit().
UpdateableContainerMetadata metadata = createMetadata();
val txn = createUpdateTransaction(metadata);
StreamSegmentAppendOperation committedAppend = createAppendNoOffset();
txn.preProcessOperation(committedAppend);
txn.acceptOperation(committedAppend);
// This is the last extent of the modifications to the metadata.
txn.commit(metadata);
int appendCount = 500;
ArrayList<StorageOperation> operations = new ArrayList<>();
for (int i = 0; i < appendCount; i++) {
operations.add(createAppendNoOffset());
}
operations.add(createMerge());
operations.add(createSeal());
long seqNo = 0;
for (StorageOperation op : operations) {
txn.preProcessOperation(op);
op.setSequenceNumber(++seqNo);
txn.acceptOperation(op);
}
txn.clear();
long expectedLength = SEGMENT_LENGTH + DEFAULT_APPEND_DATA.getLength();
// Verify metadata is untouched and that the updater has truly rolled back.
SegmentMetadata parentMetadata = metadata.getStreamSegmentMetadata(SEGMENT_ID);
Assert.assertEquals("Unexpected Length in metadata after rollback.", expectedLength, parentMetadata.getLength());
Assert.assertFalse("Unexpected value for isSealed in metadata after rollback.", parentMetadata.isSealed());
checkLastKnownSequenceNumber("Unexpected lastUsed for Target after rollback.", 0, parentMetadata);
SegmentMetadata transactionMetadata = metadata.getStreamSegmentMetadata(SEALED_SOURCE_ID);
Assert.assertFalse("Unexpected value for isMerged in transaction segment metadata after rollback.", transactionMetadata.isMerged());
checkLastKnownSequenceNumber("Unexpected lastUsed for Transaction segment after rollback.", 0, transactionMetadata);
// Now the updater
parentMetadata = txn.getStreamSegmentMetadata(SEGMENT_ID);
Assert.assertEquals("Unexpected Length in transaction after rollback.", expectedLength, parentMetadata.getLength());
Assert.assertFalse("Unexpected value for isSealed in transaction after rollback.", parentMetadata.isSealed());
checkLastKnownSequenceNumber("Unexpected lastUsed for Parent (txn) after rollback.", 0, parentMetadata);
transactionMetadata = txn.getStreamSegmentMetadata(SEALED_SOURCE_ID);
Assert.assertFalse("Unexpected value for isMerged in transaction segment in update transaction after rollback.", transactionMetadata.isMerged());
checkLastKnownSequenceNumber("Unexpected lastUsed for Transaction segment in update transaction after rollback.", 0, transactionMetadata);
}
use of io.pravega.segmentstore.server.SegmentMetadata in project pravega by pravega.
the class ContainerMetadataUpdateTransactionTests method testCommit.
private void testCommit(UpdateableContainerMetadata baseMetadata, UpdateableContainerMetadata targetMetadata) throws Exception {
// Create a few appends, merge a Transaction and seal the target Segment. Verify all changes have been applied after
// a call to commit().
int appendCount = 500;
ArrayList<StorageOperation> operations = new ArrayList<>();
int appendAttributeCount = 0;
for (int i = 0; i < appendCount; i++) {
StreamSegmentAppendOperation op = createAppendNoOffset();
operations.add(op);
appendAttributeCount += op.getAttributeUpdates().size();
}
operations.add(createMerge());
operations.add(createSeal());
// This is a change we make only to the baseMetadata. This should not propagate to the targetMetadata.
baseMetadata.getStreamSegmentMetadata(SEGMENT_ID).updateAttributes(Collections.singletonMap(Attributes.CREATION_TIME, 0L));
val txn = createUpdateTransaction(baseMetadata);
long expectedLastUsedParent = -1;
long expectedLastUsedTransaction = -1;
long seqNo = 0;
for (StorageOperation op : operations) {
txn.preProcessOperation(op);
op.setSequenceNumber(++seqNo);
txn.acceptOperation(op);
if (op.getStreamSegmentId() == SEGMENT_ID) {
expectedLastUsedParent = op.getSequenceNumber();
}
if (op instanceof MergeSegmentOperation) {
expectedLastUsedParent = op.getSequenceNumber();
expectedLastUsedTransaction = op.getSequenceNumber();
}
}
txn.commit(targetMetadata);
Assert.assertEquals("commit() seems to have modified the metadata sequence number while not in recovery mode.", ContainerMetadata.INITIAL_OPERATION_SEQUENCE_NUMBER, targetMetadata.nextOperationSequenceNumber() - 1);
long expectedLength = SEGMENT_LENGTH + appendCount * DEFAULT_APPEND_DATA.getLength() + SEALED_SOURCE_LENGTH;
SegmentMetadata parentMetadata = targetMetadata.getStreamSegmentMetadata(SEGMENT_ID);
Assert.assertEquals("Unexpected Length in metadata after commit.", expectedLength, parentMetadata.getLength());
Assert.assertTrue("Unexpected value for isSealed in metadata after commit.", parentMetadata.isSealed());
checkLastKnownSequenceNumber("Unexpected lastUsed for Target after commit.", expectedLastUsedParent, parentMetadata);
SegmentMetadata transactionMetadata = targetMetadata.getStreamSegmentMetadata(SEALED_SOURCE_ID);
Assert.assertTrue("Unexpected value for isSealed in Source metadata after commit.", transactionMetadata.isSealed());
Assert.assertTrue("Unexpected value for isMerged in Source metadata after commit.", transactionMetadata.isMerged());
int expectedParentAttributeCount = appendAttributeCount + (baseMetadata == targetMetadata ? 1 : 0) + 1;
Assert.assertEquals("Unexpected number of attributes for Target segment.", expectedParentAttributeCount, parentMetadata.getAttributes().size());
Assert.assertEquals(DEFAULT_TYPE.getValue(), (long) parentMetadata.getAttributes().get(Attributes.ATTRIBUTE_SEGMENT_TYPE));
Assert.assertEquals("Unexpected number of attributes for Source.", 1, transactionMetadata.getAttributes().size());
Assert.assertEquals(DEFAULT_TYPE.getValue(), (long) transactionMetadata.getAttributes().get(Attributes.ATTRIBUTE_SEGMENT_TYPE));
checkLastKnownSequenceNumber("Unexpected lastUsed for Source after commit.", expectedLastUsedTransaction, transactionMetadata);
}
use of io.pravega.segmentstore.server.SegmentMetadata in project pravega by pravega.
the class StreamSegmentContainer method addOperation.
private <T extends Operation & SegmentOperation> CompletableFuture<Void> addOperation(T operation, Duration timeout) {
SegmentMetadata sm = this.metadata.getStreamSegmentMetadata(operation.getStreamSegmentId());
OperationPriority priority = calculatePriority(sm.getType(), operation);
return this.durableLog.add(operation, priority, timeout);
}
use of io.pravega.segmentstore.server.SegmentMetadata in project pravega by pravega.
the class ContainerAttributeIndexImpl method forSegment.
// endregion
// region ContainerAttributeIndex Implementation
@Override
public CompletableFuture<AttributeIndex> forSegment(long streamSegmentId, Duration timeout) {
Exceptions.checkNotClosed(this.closed.get(), this);
SegmentMetadata sm = this.containerMetadata.getStreamSegmentMetadata(streamSegmentId);
if (sm.isDeleted()) {
return Futures.failedFuture(new StreamSegmentNotExistsException(sm.getName()));
}
// Figure out if we already have this AttributeIndex cached. If not, we need to initialize it.
CompletableFuture<AttributeIndex> result;
AtomicReference<SegmentAttributeBTreeIndex> toInitialize = new AtomicReference<>();
synchronized (this.attributeIndices) {
result = this.attributeIndices.computeIfAbsent(streamSegmentId, id -> {
toInitialize.set(new SegmentAttributeBTreeIndex(sm, this.storage, this.cacheManager.getCacheStorage(), this.config, this.executor));
return new CompletableFuture<>();
});
}
if (toInitialize.get() == null) {
// its initialization is done).
return result;
} else {
try {
// Need to initialize the AttributeIndex and complete the future that we just registered.
// If this fails, we must fail the Future that we previously registered and unregister any pointers to
// this index.
toInitialize.get().initialize(timeout).thenRun(() -> this.cacheManager.register(toInitialize.get())).whenComplete((r, ex) -> {
if (ex == null) {
result.complete(toInitialize.get());
} else {
indexInitializationFailed(streamSegmentId, result, ex);
}
});
} catch (Throwable ex) {
if (!Exceptions.mustRethrow(ex)) {
indexInitializationFailed(streamSegmentId, result, ex);
}
throw ex;
}
}
return result;
}
Aggregations