Search in sources :

Example 31 with SegmentHandle

use of io.pravega.segmentstore.storage.SegmentHandle in project pravega by pravega.

the class SegmentAttributeBTreeIndex method readPage.

private CompletableFuture<ByteArraySegment> readPage(long offset, int length, boolean cacheResult, Duration timeout) {
    // First, check in the cache.
    byte[] fromCache = getFromCache(offset, length);
    if (fromCache != null) {
        return CompletableFuture.completedFuture(new ByteArraySegment(fromCache));
    }
    // Cache miss; load data from Storage.
    SegmentHandle handle = this.handle.get();
    if (handle == null) {
        // Attribute Segment does not exist.
        if (offset == 0 && length == 0) {
            // Reading 0 bytes at offset 0 is a valid operation (inexistent Attribute Segment is equivalent to an empty one).
            return CompletableFuture.completedFuture(new ByteArraySegment(new byte[0]));
        } else {
            return Futures.failedFuture(new ArrayIndexOutOfBoundsException(String.format("Attribute Index Segment has not been created yet. Cannot read %d byte(s) from offset (%d).", length, offset)));
        }
    }
    return readPageFromStorage(handle, offset, length, cacheResult, timeout);
}
Also used : ByteArraySegment(io.pravega.common.util.ByteArraySegment) SegmentHandle(io.pravega.segmentstore.storage.SegmentHandle)

Example 32 with SegmentHandle

use of io.pravega.segmentstore.storage.SegmentHandle in project pravega by pravega.

the class SegmentAttributeBTreeIndex method readPageFromStorage.

private CompletableFuture<ByteArraySegment> readPageFromStorage(SegmentHandle handle, PendingRead pr, boolean cacheResult, Duration timeout) {
    byte[] buffer = new byte[pr.length];
    Futures.completeAfter(() -> this.storage.read(handle, pr.offset, buffer, 0, pr.length, timeout).thenApplyAsync(bytesRead -> {
        Preconditions.checkArgument(pr.length == bytesRead, "Unexpected number of bytes read.");
        if (cacheResult) {
            storeInCache(pr.offset, buffer);
        }
        return new ByteArraySegment(buffer);
    }, this.executor), pr.completion);
    return pr.completion;
}
Also used : Storage(io.pravega.segmentstore.storage.Storage) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) SneakyThrows(lombok.SneakyThrows) Retry(io.pravega.common.util.Retry) RequiredArgsConstructor(lombok.RequiredArgsConstructor) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties) StreamSegmentSealedException(io.pravega.segmentstore.contracts.StreamSegmentSealedException) SegmentHandle(io.pravega.segmentstore.storage.SegmentHandle) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BufferView(io.pravega.common.util.BufferView) Duration(java.time.Duration) Map(java.util.Map) Attributes(io.pravega.segmentstore.contracts.Attributes) NonNull(lombok.NonNull) Collection(java.util.Collection) CompletionException(java.util.concurrent.CompletionException) GuardedBy(javax.annotation.concurrent.GuardedBy) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) ByteArraySegment(io.pravega.common.util.ByteArraySegment) PageEntry(io.pravega.common.util.btree.PageEntry) StreamSegmentExistsException(io.pravega.segmentstore.contracts.StreamSegmentExistsException) BadOffsetException(io.pravega.segmentstore.contracts.BadOffsetException) Futures(io.pravega.common.concurrent.Futures) CacheManager(io.pravega.segmentstore.server.CacheManager) Getter(lombok.Getter) Exceptions(io.pravega.common.Exceptions) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) CacheStorage(io.pravega.segmentstore.storage.cache.CacheStorage) ArrayList(java.util.ArrayList) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) BTreeIndex(io.pravega.common.util.btree.BTreeIndex) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) CacheFullException(io.pravega.segmentstore.storage.cache.CacheFullException) AttributeIterator(io.pravega.segmentstore.server.AttributeIterator) StreamSegmentTruncatedException(io.pravega.segmentstore.contracts.StreamSegmentTruncatedException) NameUtils(io.pravega.shared.NameUtils) AttributeIndex(io.pravega.segmentstore.server.AttributeIndex) TimeoutTimer(io.pravega.common.TimeoutTimer) SequenceInputStream(java.io.SequenceInputStream) AttributeId(io.pravega.segmentstore.contracts.AttributeId) lombok.val(lombok.val) AsyncIterator(io.pravega.common.util.AsyncIterator) Maps(com.google.common.collect.Maps) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) IllegalDataFormatException(io.pravega.common.util.IllegalDataFormatException) DataCorruptionException(io.pravega.segmentstore.server.DataCorruptionException) AllArgsConstructor(lombok.AllArgsConstructor) Collections(java.util.Collections) InputStream(java.io.InputStream) ByteArraySegment(io.pravega.common.util.ByteArraySegment)

Example 33 with SegmentHandle

use of io.pravega.segmentstore.storage.SegmentHandle in project pravega by pravega.

the class SegmentAttributeBTreeIndex method seal.

@Override
public CompletableFuture<Void> seal(@NonNull Duration timeout) {
    ensureInitialized();
    SegmentHandle handle = this.handle.get();
    if (handle == null) {
        // Empty Attribute Index. There is no point in sealing since we won't be allowed to update anything new from now on.
        return CompletableFuture.completedFuture(null);
    }
    return Futures.exceptionallyExpecting(this.storage.seal(handle, timeout).thenRun(() -> log.info("{}: Sealed.", this.traceObjectId)), ex -> ex instanceof StreamSegmentSealedException, null);
}
Also used : StreamSegmentSealedException(io.pravega.segmentstore.contracts.StreamSegmentSealedException) SegmentHandle(io.pravega.segmentstore.storage.SegmentHandle)

Example 34 with SegmentHandle

use of io.pravega.segmentstore.storage.SegmentHandle in project pravega by pravega.

the class ChunkedSegmentStorageTests method testTruncateWithFailover.

@Test
public void testTruncateWithFailover() throws Exception {
    @Cleanup CleanupHelper cleanupHelper = new CleanupHelper();
    String testSegmentName = "foo";
    val config = ChunkedSegmentStorageConfig.DEFAULT_CONFIG.toBuilder().garbageCollectionDelay(Duration.ZERO).indexBlockSize(3).build();
    TestContext testContext = getTestContext(config);
    cleanupHelper.add(testContext);
    // Create
    testContext.chunkedSegmentStorage.create(testSegmentName, null).get();
    // Write some data.
    long offset = 0;
    int i = 2;
    long epoch = testContext.chunkedSegmentStorage.getEpoch();
    SegmentHandle hWrite = testContext.chunkedSegmentStorage.openWrite(testSegmentName).get();
    // Create a new test context and initialize with new epoch.
    testContext.chunkedSegmentStorage.write(hWrite, offset, new ByteArrayInputStream(new byte[i]), i, null).join();
    TestUtils.checkSegmentBounds(testContext.metadataStore, testSegmentName, offset, offset + i);
    TestUtils.checkReadIndexEntries(testContext.chunkedSegmentStorage, testContext.metadataStore, testSegmentName, offset, offset + i, true);
    checkDataRead(testSegmentName, testContext, offset, i);
    offset += i;
    // Fork the context.
    testContext = testContext.fork(++epoch);
    cleanupHelper.add(testContext);
    val oldTestCotext = testContext;
    val newTestContext = oldTestCotext.fork(++epoch);
    cleanupHelper.add(newTestContext);
    // Fence out old store.
    oldTestCotext.metadataStore.markFenced();
    // Truncate and Read in new epoch.
    // Make sure to open segment with new instance before writing garbage to old instance.
    hWrite = newTestContext.chunkedSegmentStorage.openWrite(testSegmentName).get();
    newTestContext.chunkedSegmentStorage.truncate(hWrite, offset, null).get();
    TestUtils.checkSegmentBounds(newTestContext.metadataStore, testSegmentName, offset, offset);
    TestUtils.checkReadIndexEntries(newTestContext.chunkedSegmentStorage, newTestContext.metadataStore, testSegmentName, offset, offset, false);
    AssertExtensions.assertFutureThrows("openWrite() allowed after fencing", oldTestCotext.chunkedSegmentStorage.openWrite(testSegmentName), ex -> ex instanceof StorageNotPrimaryException);
    AssertExtensions.assertFutureThrows("openRead() allowed after fencing", oldTestCotext.chunkedSegmentStorage.openRead(testSegmentName), ex -> ex instanceof StorageNotPrimaryException);
}
Also used : lombok.val(lombok.val) ByteArrayInputStream(java.io.ByteArrayInputStream) Cleanup(lombok.Cleanup) SegmentHandle(io.pravega.segmentstore.storage.SegmentHandle) StorageNotPrimaryException(io.pravega.segmentstore.storage.StorageNotPrimaryException) Test(org.junit.Test)

Example 35 with SegmentHandle

use of io.pravega.segmentstore.storage.SegmentHandle in project pravega by pravega.

the class ChunkedSegmentStorageTests method testReadWriteWithMultipleFailoversWithGarbage.

/**
 * Test read and write with multiple failovers.
 *
 * @throws Exception Exception if any.
 */
@Test
public void testReadWriteWithMultipleFailoversWithGarbage() throws Exception {
    @Cleanup CleanupHelper cleanupHelper = new CleanupHelper();
    String testSegmentName = "foo";
    @Cleanup TestContext testContext = getTestContext();
    cleanupHelper.add(testContext);
    // Create
    testContext.chunkedSegmentStorage.create(testSegmentName, null).get();
    // Write some data.
    long writeAt = 0;
    long epoch = CONTAINER_ID;
    SegmentHandle hWrite = testContext.chunkedSegmentStorage.openWrite(testSegmentName).get();
    ArrayList<Long> lengths = new ArrayList<>();
    for (int i = 1; i < 5; i++) {
        // Create a new test context and initialize with new epoch.
        testContext.chunkedSegmentStorage.write(hWrite, writeAt, new ByteArrayInputStream(new byte[i]), i, null).join();
        writeAt += i;
        lengths.add((long) i);
        // Read in same epoch.
        checkDataRead(testSegmentName, testContext, 0, writeAt);
        val lengthsArray = Longs.toArray(lengths);
        TestUtils.checkSegmentLayout(testContext.metadataStore, testSegmentName, lengthsArray);
        TestUtils.checkReadIndexEntries(testContext.chunkedSegmentStorage, testContext.metadataStore, testSegmentName, 0, Arrays.stream(lengthsArray).sum(), false);
        // Fork the context.
        val oldTestCotext = testContext;
        testContext = oldTestCotext.fork(epoch++);
        cleanupHelper.add(testContext);
        TestUtils.checkSegmentLayout(testContext.metadataStore, testSegmentName, Longs.toArray(lengths));
        // Make sure to open segment with new instance before writing garbage to old instance.
        hWrite = testContext.chunkedSegmentStorage.openWrite(testSegmentName).get();
        // Write some garbage
        oldTestCotext.chunkedSegmentStorage.write(hWrite, writeAt, new ByteArrayInputStream(new byte[10]), 10, null).join();
        // Fence out old store.
        oldTestCotext.metadataStore.markFenced();
        AssertExtensions.assertFutureThrows("write() allowed after fencing", oldTestCotext.chunkedSegmentStorage.write(hWrite, writeAt + 10, new ByteArrayInputStream(new byte[10]), 10, null), ex -> ex instanceof StorageNotPrimaryException);
        // Read in new epoch.
        checkDataRead(testSegmentName, testContext, 0, writeAt);
    }
    int total = 10;
    // Create a new test context and initialize with new epoch.
    testContext = testContext.fork(epoch++);
    cleanupHelper.add(testContext);
    checkDataRead(testSegmentName, testContext, 0, total);
}
Also used : lombok.val(lombok.val) ArrayList(java.util.ArrayList) Cleanup(lombok.Cleanup) SegmentHandle(io.pravega.segmentstore.storage.SegmentHandle) ByteArrayInputStream(java.io.ByteArrayInputStream) StorageNotPrimaryException(io.pravega.segmentstore.storage.StorageNotPrimaryException) Test(org.junit.Test)

Aggregations

SegmentHandle (io.pravega.segmentstore.storage.SegmentHandle)43 lombok.val (lombok.val)27 Test (org.junit.Test)26 Storage (io.pravega.segmentstore.storage.Storage)20 ByteArrayInputStream (java.io.ByteArrayInputStream)20 StreamSegmentNotExistsException (io.pravega.segmentstore.contracts.StreamSegmentNotExistsException)14 SegmentProperties (io.pravega.segmentstore.contracts.SegmentProperties)13 StreamSegmentSealedException (io.pravega.segmentstore.contracts.StreamSegmentSealedException)12 StorageNotPrimaryException (io.pravega.segmentstore.storage.StorageNotPrimaryException)12 Exceptions (io.pravega.common.Exceptions)10 Cleanup (lombok.Cleanup)10 CompletableFuture (java.util.concurrent.CompletableFuture)9 Futures (io.pravega.common.concurrent.Futures)8 StreamSegmentExistsException (io.pravega.segmentstore.contracts.StreamSegmentExistsException)8 NameUtils (io.pravega.shared.NameUtils)8 List (java.util.List)8 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)8 Preconditions (com.google.common.base.Preconditions)7 StreamSegmentInformation (io.pravega.segmentstore.contracts.StreamSegmentInformation)7 SegmentRollingPolicy (io.pravega.segmentstore.storage.SegmentRollingPolicy)7