Search in sources :

Example 41 with SegmentMetadata

use of io.pravega.segmentstore.server.SegmentMetadata in project pravega by pravega.

the class StorageWriterTests method verifyFinalOutput.

// region Helpers
private void verifyFinalOutput(HashMap<Long, ByteArrayOutputStream> segmentContents, Collection<Long> transactionIds, TestContext context) {
    // Verify all Transactions are deleted.
    for (long transactionId : transactionIds) {
        SegmentMetadata metadata = context.metadata.getStreamSegmentMetadata(transactionId);
        Assert.assertTrue("Transaction not marked as deleted in metadata: " + transactionId, metadata.isDeleted());
        Assert.assertFalse("Transaction was not deleted from storage after being merged: " + transactionId, context.storage.exists(metadata.getName(), TIMEOUT).join());
        verifyAttributes(metadata, context);
    }
    for (long segmentId : segmentContents.keySet()) {
        SegmentMetadata metadata = context.metadata.getStreamSegmentMetadata(segmentId);
        Assert.assertNotNull("Setup error: No metadata for segment " + segmentId, metadata);
        Assert.assertFalse("Setup error: Not expecting a Transaction segment in the final list: " + segmentId, context.transactionIds.containsKey(metadata.getId()));
        Assert.assertEquals("Metadata does not indicate that all bytes were copied to Storage for segment " + segmentId, metadata.getLength(), metadata.getStorageLength());
        Assert.assertEquals("Metadata.Sealed disagrees with Metadata.SealedInStorage for segment " + segmentId, metadata.isSealed(), metadata.isSealedInStorage());
        SegmentProperties sp = context.storage.getStreamSegmentInfo(metadata.getName(), TIMEOUT).join();
        Assert.assertEquals("Metadata.StorageLength disagrees with Storage.Length for segment " + segmentId, metadata.getStorageLength(), sp.getLength());
        Assert.assertEquals("Metadata.Sealed/SealedInStorage disagrees with Storage.Sealed for segment " + segmentId, metadata.isSealedInStorage(), sp.isSealed());
        byte[] expected = segmentContents.get(segmentId).toByteArray();
        byte[] actual = new byte[expected.length];
        int actualLength = context.storage.read(InMemoryStorage.newHandle(metadata.getName(), true), 0, actual, 0, actual.length, TIMEOUT).join();
        Assert.assertEquals("Unexpected number of bytes read from Storage for segment " + segmentId, metadata.getStorageLength(), actualLength);
        Assert.assertArrayEquals("Unexpected data written to storage for segment " + segmentId, expected, actual);
        Assert.assertEquals("Unexpected truncation offset for segment " + segmentId, metadata.getStartOffset(), context.storage.getTruncationOffset(metadata.getName()));
        verifyAttributes(metadata, context);
    }
}
Also used : UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties)

Example 42 with SegmentMetadata

use of io.pravega.segmentstore.server.SegmentMetadata in project pravega by pravega.

the class StorageWriterTests method createTransactions.

private HashMap<Long, ArrayList<Long>> createTransactions(Collection<Long> segmentIds, TestContext context) {
    // Create the Transactions.
    HashMap<Long, ArrayList<Long>> transactions = new HashMap<>();
    long transactionId = Integer.MAX_VALUE;
    for (long parentId : segmentIds) {
        ArrayList<Long> segmentTransactions = new ArrayList<>();
        transactions.put(parentId, segmentTransactions);
        SegmentMetadata parentMetadata = context.metadata.getStreamSegmentMetadata(parentId);
        for (int i = 0; i < TRANSACTIONS_PER_SEGMENT; i++) {
            String transactionName = NameUtils.getTransactionNameFromId(parentMetadata.getName(), UUID.randomUUID());
            context.transactionIds.put(transactionId, parentId);
            context.metadata.mapStreamSegmentId(transactionName, transactionId);
            initializeSegment(transactionId, context);
            segmentTransactions.add(transactionId);
            // Add the operation to the log.
            StreamSegmentMapOperation mapOp = new StreamSegmentMapOperation(context.storage.getStreamSegmentInfo(transactionName, TIMEOUT).join());
            mapOp.setStreamSegmentId(transactionId);
            context.dataSource.add(mapOp);
            transactionId++;
        }
    }
    return transactions;
}
Also used : UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) StreamSegmentMapOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentMapOperation)

Example 43 with SegmentMetadata

use of io.pravega.segmentstore.server.SegmentMetadata in project pravega by pravega.

the class MetadataStoreTestBase method testGetOrAssignStreamSegmentId.

/**
 * Tests the ability of the MetadataStore to generate/return the Id of an existing StreamSegment, as well as
 * retrieving existing attributes.
 */
@Test
public void testGetOrAssignStreamSegmentId() {
    final long baseSegmentId = 1000;
    final long minSegmentLength = 1;
    final int segmentCount = 50;
    Function<String, Long> getSegmentLength = segmentName -> minSegmentLength + MathHelpers.abs(segmentName.hashCode());
    Function<String, Long> getSegmentStartOffset = segmentName -> getSegmentLength.apply(segmentName) / 2;
    @Cleanup TestContext context = createTestContext();
    HashSet<String> segmentNames = new HashSet<>();
    HashSet<String> sealedSegments = new HashSet<>();
    for (int i = 0; i < segmentCount; i++) {
        String segmentName = getName(i);
        segmentNames.add(segmentName);
        val si = StreamSegmentInformation.builder().name(segmentName).length(getSegmentLength.apply(segmentName)).startOffset(getSegmentStartOffset.apply(segmentName)).sealed(i % 2 == 0).attributes(toAttributes(createAttributeUpdates(ATTRIBUTE_COUNT))).build();
        if (si.isSealed()) {
            sealedSegments.add(segmentName);
        }
        context.getMetadataStore().updateSegmentInfo(toMetadata(baseSegmentId + i, si), TIMEOUT).join();
    }
    Predicate<String> isSealed = sealedSegments::contains;
    for (String name : segmentNames) {
        long id = context.getMetadataStore().getOrAssignSegmentId(name, TIMEOUT).join();
        Assert.assertNotEquals("No id was assigned for StreamSegment " + name, ContainerMetadata.NO_STREAM_SEGMENT_ID, id);
        SegmentMetadata sm = context.getMetadata().getStreamSegmentMetadata(id);
        Assert.assertNotNull("No metadata was created for StreamSegment " + name, sm);
        long expectedLength = getSegmentLength.apply(name);
        boolean expectedSeal = isSealed.test(name);
        Assert.assertEquals("Metadata does not have the expected length for StreamSegment " + name, expectedLength, sm.getLength());
        Assert.assertEquals("Metadata does not have the expected value for isSealed for StreamSegment " + name, expectedSeal, sm.isSealed());
        val segmentState = context.getMetadataStore().getSegmentInfo(name, TIMEOUT).join();
        Map<AttributeId, Long> expectedAttributes = segmentState == null ? null : segmentState.getAttributes();
        SegmentMetadataComparer.assertSameAttributes("Unexpected attributes in metadata for StreamSegment " + name, expectedAttributes, sm);
        long expectedStartOffset = segmentState == null ? 0 : segmentState.getStartOffset();
        Assert.assertEquals("Unexpected StartOffset in metadata for " + name, expectedStartOffset, sm.getStartOffset());
    }
}
Also used : Arrays(java.util.Arrays) StreamSegmentInformation(io.pravega.segmentstore.contracts.StreamSegmentInformation) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) SneakyThrows(lombok.SneakyThrows) AssertExtensions(io.pravega.test.common.AssertExtensions) RequiredArgsConstructor(lombok.RequiredArgsConstructor) ContainerMetadata(io.pravega.segmentstore.server.ContainerMetadata) TimeoutException(java.util.concurrent.TimeoutException) Cleanup(lombok.Cleanup) UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Map(java.util.Map) Attributes(io.pravega.segmentstore.contracts.Attributes) ImmutableMap(com.google.common.collect.ImmutableMap) Predicate(java.util.function.Predicate) Collection(java.util.Collection) Set(java.util.Set) UUID(java.util.UUID) GuardedBy(javax.annotation.concurrent.GuardedBy) Collectors(java.util.stream.Collectors) SegmentMetadataComparer(io.pravega.segmentstore.server.SegmentMetadataComparer) ErrorInjector(io.pravega.test.common.ErrorInjector) List(java.util.List) Stream(java.util.stream.Stream) StreamSegmentExistsException(io.pravega.segmentstore.contracts.StreamSegmentExistsException) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) TestUtils(io.pravega.test.common.TestUtils) Futures(io.pravega.common.concurrent.Futures) ObjectClosedException(io.pravega.common.ObjectClosedException) MetadataBuilder(io.pravega.segmentstore.server.MetadataBuilder) Setter(lombok.Setter) Getter(lombok.Getter) TooManyActiveSegmentsException(io.pravega.segmentstore.contracts.TooManyActiveSegmentsException) Exceptions(io.pravega.common.Exceptions) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) SegmentType(io.pravega.segmentstore.contracts.SegmentType) MathHelpers(io.pravega.common.MathHelpers) NameUtils(io.pravega.shared.NameUtils) AttributeId(io.pravega.segmentstore.contracts.AttributeId) IntentionalException(io.pravega.test.common.IntentionalException) lombok.val(lombok.val) Test(org.junit.Test) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) AttributeUpdateCollection(io.pravega.segmentstore.contracts.AttributeUpdateCollection) AttributeUpdateType(io.pravega.segmentstore.contracts.AttributeUpdateType) Assert(org.junit.Assert) Collections(java.util.Collections) lombok.val(lombok.val) AttributeId(io.pravega.segmentstore.contracts.AttributeId) Cleanup(lombok.Cleanup) UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 44 with SegmentMetadata

use of io.pravega.segmentstore.server.SegmentMetadata in project pravega by pravega.

the class MetadataCleanerTests method testCleanup.

/**
 * Tests {@link MetadataCleaner#runOnce()}.
 */
@Test
public void testCleanup() throws Exception {
    @Cleanup val context = new TestContext();
    Assert.assertNotEquals(0, context.metadata.getActiveSegmentCount());
    // Cleanup #1. We expect half of the deleted segments to be evicted (due to how they're set up).
    val expected1 = context.metadata.getEvictionCandidates(0, 1000);
    AssertExtensions.assertGreaterThan("Expected at least one eligible segment.", 0, expected1.size());
    context.cleaner.runOnce().get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
    AssertExtensions.assertContainsSameElements("Unexpected evicted segments on the first round.", expected1, context.cleanedUpMetadata, Comparator.comparingLong(SegmentMetadata::getId));
    // Cleanup #2. We expect all the remaining evictable segments to be evicted.
    context.cleanedUpMetadata.clear();
    val expected2 = context.metadata.getEvictionCandidates(context.metadata.getOperationSequenceNumber(), 1000);
    AssertExtensions.assertGreaterThan("Expected at least one eligible segment.", 0, expected2.size());
    context.cleaner.runOnce().get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
    AssertExtensions.assertContainsSameElements("Unexpected evicted segments on the second round.", expected2, context.cleanedUpMetadata, Comparator.comparingLong(SegmentMetadata::getId));
    // Verify that we have properly evicted the attributes that we should have.
    val nonEvictedSegmentIds = context.metadata.getAllStreamSegmentIds();
    AssertExtensions.assertGreaterThan("", 0, nonEvictedSegmentIds.size());
    for (val segmentId : nonEvictedSegmentIds) {
        val sm = context.metadata.getStreamSegmentMetadata(segmentId);
        if (sm.isDeleted() || sm.isMerged()) {
            continue;
        }
        val attributeCount = sm.getAttributes((k, v) -> !Attributes.isCoreAttribute(k)).size();
        assertEquals("Unexpected number of remaining non-core attributes.", CONFIG.getMaxCachedExtendedAttributeCount(), attributeCount);
    }
}
Also used : lombok.val(lombok.val) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) AssertExtensions(io.pravega.test.common.AssertExtensions) TimeoutException(java.util.concurrent.TimeoutException) Cleanup(lombok.Cleanup) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ArrayList(java.util.ArrayList) ArrayView(io.pravega.common.util.ArrayView) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) SegmentType(io.pravega.segmentstore.contracts.SegmentType) BufferView(io.pravega.common.util.BufferView) Duration(java.time.Duration) Map(java.util.Map) Attributes(io.pravega.segmentstore.contracts.Attributes) TimeoutTimer(io.pravega.common.TimeoutTimer) NonNull(lombok.NonNull) AttributeId(io.pravega.segmentstore.contracts.AttributeId) lombok.val(lombok.val) Assert.assertTrue(org.junit.Assert.assertTrue) CompletionException(java.util.concurrent.CompletionException) Test(org.junit.Test) GuardedBy(javax.annotation.concurrent.GuardedBy) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) ByteArraySegment(io.pravega.common.util.ByteArraySegment) StreamSegmentExistsException(io.pravega.segmentstore.contracts.StreamSegmentExistsException) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) Comparator(java.util.Comparator) Assert(org.junit.Assert) Collections(java.util.Collections) Futures(io.pravega.common.concurrent.Futures) Assert.assertEquals(org.junit.Assert.assertEquals) Cleanup(lombok.Cleanup) Test(org.junit.Test)

Example 45 with SegmentMetadata

use of io.pravega.segmentstore.server.SegmentMetadata in project pravega by pravega.

the class StreamSegmentContainerMetadataTests method testGetEvictionCandidates.

/**
 * Tests the ability to identify Segment Metadatas that are not in use anymore and are eligible for eviction.
 * 1. Creates a number of segments.
 * 2. Truncates repeatedly and at each step verifies that the correct segments were identified as candidates.
 * 3. "Expires" all segments and verifies they are all identified as candidates.
 */
@Test
public void testGetEvictionCandidates() {
    // Expire each segment at a different stage.
    final long firstStageExpiration = SEGMENT_COUNT;
    final long finalExpiration = firstStageExpiration + SEGMENT_COUNT;
    // Create a number of segments.
    // Each segment has a 'LastKnownSequenceNumber' set in incremental order.
    final ArrayList<Long> segments = new ArrayList<>();
    final StreamSegmentContainerMetadata m = new MetadataBuilder(CONTAINER_ID).buildAs();
    populateSegmentsForEviction(segments, m);
    for (int i = 0; i < segments.size(); i++) {
        UpdateableSegmentMetadata segmentMetadata = m.getStreamSegmentMetadata(segments.get(i));
        if (i % 2 == 0) {
            // 1/2 of segments expire at the end.
            segmentMetadata.setLastUsed(finalExpiration);
        } else {
            // The rest of the segments expire in the first stage.
            segmentMetadata.setLastUsed(firstStageExpiration);
        }
    }
    // Add one segment that will be deleted. This should be evicted as soon as its LastUsed is before the truncation point.
    final long deletedSegmentId = segments.size();
    UpdateableSegmentMetadata deletedSegment = m.mapStreamSegmentId(getName(deletedSegmentId), deletedSegmentId);
    deletedSegment.markDeleted();
    deletedSegment.setLastUsed(firstStageExpiration);
    segments.add(deletedSegmentId);
    // Verify that not-yet-truncated operations will not be selected for truncation.
    val truncationPoints = Arrays.asList(0L, firstStageExpiration, finalExpiration, finalExpiration + 1);
    Collection<SegmentMetadata> evictionCandidates;
    for (long truncatedSeqNo : truncationPoints) {
        // Simulate a truncation.
        m.removeTruncationMarkers(truncatedSeqNo);
        // Try to evict everything.
        evictionCandidates = m.getEvictionCandidates(finalExpiration + 1, Integer.MAX_VALUE);
        checkEvictedSegmentCandidates(evictionCandidates, m, finalExpiration + 1, truncatedSeqNo);
    }
    // Now we expire all segments.
    evictionCandidates = m.getEvictionCandidates(finalExpiration + 1, Integer.MAX_VALUE);
    checkEvictedSegmentCandidates(evictionCandidates, m, finalExpiration + 1, Long.MAX_VALUE);
    // Check that, in the end, all segments in the metadata have been selected for eviction.
    Assert.assertEquals("Not all segments were evicted.", segments.size(), evictionCandidates.size());
}
Also used : lombok.val(lombok.val) UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) MetadataBuilder(io.pravega.segmentstore.server.MetadataBuilder) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Aggregations

SegmentMetadata (io.pravega.segmentstore.server.SegmentMetadata)58 UpdateableSegmentMetadata (io.pravega.segmentstore.server.UpdateableSegmentMetadata)41 lombok.val (lombok.val)25 ArrayList (java.util.ArrayList)24 Test (org.junit.Test)23 StreamSegmentNotExistsException (io.pravega.segmentstore.contracts.StreamSegmentNotExistsException)20 Duration (java.time.Duration)18 HashMap (java.util.HashMap)18 CompletableFuture (java.util.concurrent.CompletableFuture)18 Futures (io.pravega.common.concurrent.Futures)17 Collectors (java.util.stream.Collectors)17 Cleanup (lombok.Cleanup)17 Exceptions (io.pravega.common.Exceptions)15 StreamSegmentMetadata (io.pravega.segmentstore.server.containers.StreamSegmentMetadata)15 AtomicLong (java.util.concurrent.atomic.AtomicLong)15 UpdateableContainerMetadata (io.pravega.segmentstore.server.UpdateableContainerMetadata)14 Collection (java.util.Collection)14 Map (java.util.Map)14 SegmentProperties (io.pravega.segmentstore.contracts.SegmentProperties)13 MetadataBuilder (io.pravega.segmentstore.server.MetadataBuilder)13