Search in sources :

Example 46 with BufferView

use of io.pravega.common.util.BufferView in project pravega by pravega.

the class SegmentAggregatorTests method getAppendData.

// endregion
// region Helpers
private void getAppendData(StorageOperation operation, OutputStream stream, TestContext context) {
    Assert.assertTrue("Not an append operation: " + operation, operation instanceof CachedStreamSegmentAppendOperation);
    BufferView result = context.dataSource.getAppendData(operation.getStreamSegmentId(), operation.getStreamSegmentOffset(), (int) operation.getLength());
    try {
        result.copyTo(stream);
    } catch (IOException ex) {
        Assert.fail("Not expecting this exception: " + ex);
    }
}
Also used : BufferView(io.pravega.common.util.BufferView) IOException(java.io.IOException) CachedStreamSegmentAppendOperation(io.pravega.segmentstore.server.logs.operations.CachedStreamSegmentAppendOperation)

Example 47 with BufferView

use of io.pravega.common.util.BufferView in project pravega by pravega.

the class WriterTableProcessorTests method checkIndex.

private void checkIndex(HashMap<BufferView, TableEntry> existingEntries, HashMap<BufferView, UUID> allKeys, TestContext context) throws Exception {
    // Get all the buckets associated with the given keys.
    val timer = new TimeoutTimer(TIMEOUT);
    val bucketsByHash = context.indexReader.locateBuckets(context.segmentMock, allKeys.values(), timer).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
    // Index the existing Keys by their current offsets.
    val keysByOffset = existingEntries.entrySet().stream().collect(Collectors.toMap(e -> e.getValue().getKey().getVersion(), Map.Entry::getKey));
    // Load up all the offsets for all buckets.
    val buckets = bucketsByHash.values().stream().distinct().collect(Collectors.toMap(b -> b, b -> context.indexReader.getBucketOffsets(context.segmentMock, b, timer).join()));
    // Loop through all the bucket's offsets and verify that those offsets do point to existing keys.
    for (val e : buckets.entrySet()) {
        val bucketOffsets = e.getValue();
        for (val offset : bucketOffsets) {
            Assert.assertTrue("Found Bucket Offset that points to non-existing key.", keysByOffset.containsKey(offset));
        }
    }
    // TableBucket, otherwise it is not included in any bucket.
    for (val e : allKeys.entrySet()) {
        val key = e.getKey();
        val tableEntry = existingEntries.get(key);
        val bucket = bucketsByHash.get(e.getValue());
        Assert.assertNotNull("Test error: no bucket found.", bucket);
        val bucketOffsets = buckets.get(bucket);
        if (tableEntry != null) {
            // This key should exist: just verify the TableEntry's offset (Key Version) exists in the Bucket's offset list.
            Assert.assertTrue("Non-deleted key was not included in a Table Bucket.", bucketOffsets.contains(tableEntry.getKey().getVersion()));
        } else {
            // Verify that all the keys that the Table Bucket points to do not match our key. Use our existing offset-key cache for that.
            for (val offset : bucketOffsets) {
                val keyAtOffset = keysByOffset.get(offset);
                Assert.assertNotEquals("Deleted key was still included in a Table Bucket.", key, keyAtOffset);
            }
        }
    }
}
Also used : lombok.val(lombok.val) ObjectClosedException(io.pravega.common.ObjectClosedException) TableAttributes(io.pravega.segmentstore.contracts.tables.TableAttributes) AssertExtensions(io.pravega.test.common.AssertExtensions) RequiredArgsConstructor(lombok.RequiredArgsConstructor) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Cleanup(lombok.Cleanup) HashMap(java.util.HashMap) Random(java.util.Random) CompletableFuture(java.util.concurrent.CompletableFuture) UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) ArrayList(java.util.ArrayList) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BufferView(io.pravega.common.util.BufferView) Duration(java.time.Duration) Map(java.util.Map) Timeout(org.junit.rules.Timeout) Operation(io.pravega.segmentstore.server.logs.operations.Operation) TableKey(io.pravega.segmentstore.contracts.tables.TableKey) TimeoutTimer(io.pravega.common.TimeoutTimer) lombok.val(lombok.val) Test(org.junit.Test) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) TimeUnit(java.util.concurrent.TimeUnit) SegmentMock(io.pravega.segmentstore.server.SegmentMock) StreamSegmentMetadata(io.pravega.segmentstore.server.containers.StreamSegmentMetadata) AtomicLong(java.util.concurrent.atomic.AtomicLong) DirectSegmentAccess(io.pravega.segmentstore.server.DirectSegmentAccess) List(java.util.List) AttributeUpdateCollection(io.pravega.segmentstore.contracts.AttributeUpdateCollection) Rule(org.junit.Rule) ByteArraySegment(io.pravega.common.util.ByteArraySegment) CachedStreamSegmentAppendOperation(io.pravega.segmentstore.server.logs.operations.CachedStreamSegmentAppendOperation) StreamSegmentAppendOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentAppendOperation) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) Preconditions(com.google.common.base.Preconditions) AttributeUpdateType(io.pravega.segmentstore.contracts.AttributeUpdateType) DataCorruptionException(io.pravega.segmentstore.server.DataCorruptionException) Assert(org.junit.Assert) TableEntry(io.pravega.segmentstore.contracts.tables.TableEntry) Collections(java.util.Collections) HashMap(java.util.HashMap) Map(java.util.Map) TimeoutTimer(io.pravega.common.TimeoutTimer)

Example 48 with BufferView

use of io.pravega.common.util.BufferView in project pravega by pravega.

the class TableSegmentLayoutTestBase method testSingleUpdates.

@SneakyThrows
protected void testSingleUpdates(KeyHasher hasher, EntryGenerator generateToUpdate, KeyGenerator generateToRemove) {
    @Cleanup val context = new TableContext(hasher, executorService());
    // Generate the keys.
    val keys = IntStream.range(0, SINGLE_UPDATE_COUNT).mapToObj(i -> createRandomKey(context)).collect(Collectors.toList());
    // Create the Segment.
    createSegment(context, SEGMENT_NAME);
    @Cleanup val processor = createWriterTableProcessor(context);
    // Update.
    val expectedEntries = new HashMap<BufferView, BufferView>();
    val removedKeys = new ArrayList<BufferView>();
    val keyVersions = new HashMap<BufferView, Long>();
    Function<BufferView, Long> getKeyVersion = k -> keyVersions.getOrDefault(k, TableKey.NOT_EXISTS);
    int totalUpdateCount = 0;
    int totalRemoveCount = 0;
    for (val key : keys) {
        val toUpdate = generateToUpdate.apply(key, createRandomData(MAX_VALUE_LENGTH, context), getKeyVersion.apply(key));
        val updateResult = new AtomicReference<List<Long>>();
        context.ext.put(SEGMENT_NAME, Collections.singletonList(toUpdate), TIMEOUT).thenAccept(updateResult::set).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
        Assert.assertEquals("Unexpected result size from update.", 1, updateResult.get().size());
        keyVersions.put(key, updateResult.get().get(0));
        expectedEntries.put(toUpdate.getKey().getKey(), toUpdate.getValue());
        check(expectedEntries, removedKeys, context.ext);
        if (processor != null) {
            processor.flush(TIMEOUT).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
            check(expectedEntries, removedKeys, context.ext);
        }
        totalUpdateCount++;
        checkTableAttributes(totalUpdateCount, totalRemoveCount, totalUpdateCount, context);
    }
    checkIterators(expectedEntries, context.ext);
    // Remove.
    for (val key : keys) {
        val toRemove = generateToRemove.apply(key, getKeyVersion.apply(key));
        context.ext.remove(SEGMENT_NAME, Collections.singleton(toRemove), TIMEOUT).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
        removedKeys.add(key);
        expectedEntries.remove(key);
        keyVersions.remove(key);
        check(expectedEntries, removedKeys, context.ext);
        if (processor != null) {
            processor.flush(TIMEOUT).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
            check(expectedEntries, removedKeys, context.ext);
        }
        totalRemoveCount++;
        checkTableAttributes(totalUpdateCount, totalRemoveCount, totalUpdateCount - totalRemoveCount, context);
    }
    checkIterators(expectedEntries, context.ext);
    deleteSegment(expectedEntries.keySet(), supportsDeleteIfEmpty(), context.ext);
}
Also used : lombok.val(lombok.val) IntStream(java.util.stream.IntStream) TableAttributes(io.pravega.segmentstore.contracts.tables.TableAttributes) BufferViewComparator(io.pravega.common.util.BufferViewComparator) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) SneakyThrows(lombok.SneakyThrows) AssertExtensions(io.pravega.test.common.AssertExtensions) RequiredArgsConstructor(lombok.RequiredArgsConstructor) Cleanup(lombok.Cleanup) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) BadKeyVersionException(io.pravega.segmentstore.contracts.tables.BadKeyVersionException) IteratorArgs(io.pravega.segmentstore.contracts.tables.IteratorArgs) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) TableSegmentNotEmptyException(io.pravega.segmentstore.contracts.tables.TableSegmentNotEmptyException) IteratorItem(io.pravega.segmentstore.contracts.tables.IteratorItem) BufferView(io.pravega.common.util.BufferView) Duration(java.time.Duration) Map(java.util.Map) TableKey(io.pravega.segmentstore.contracts.tables.TableKey) Collection(java.util.Collection) AttributeId(io.pravega.segmentstore.contracts.AttributeId) lombok.val(lombok.val) AsyncIterator(io.pravega.common.util.AsyncIterator) Test(org.junit.Test) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) ByteArraySegment(io.pravega.common.util.ByteArraySegment) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) TestUtils(io.pravega.test.common.TestUtils) Comparator(java.util.Comparator) Assert(org.junit.Assert) TableEntry(io.pravega.segmentstore.contracts.tables.TableEntry) Collections(java.util.Collections) BufferView(io.pravega.common.util.BufferView) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AtomicReference(java.util.concurrent.atomic.AtomicReference) Cleanup(lombok.Cleanup) SneakyThrows(lombok.SneakyThrows)

Example 49 with BufferView

use of io.pravega.common.util.BufferView in project pravega by pravega.

the class TableSegmentLayoutTestBase method generateAndPopulateEntriesBatch.

private TestBatchData generateAndPopulateEntriesBatch(int batchSize, TestBatchData previous, TableContext context) {
    val expectedEntries = previous == null ? new HashMap<BufferView, BufferView>() : new HashMap<>(previous.expectedEntries);
    val removalCandidates = previous == null ? new ArrayList<BufferView>() : // Need a list so we can efficiently pick removal candidates.
    new ArrayList<>(expectedEntries.keySet());
    val toUpdate = new HashMap<BufferView, BufferView>();
    val toRemove = new ArrayList<BufferView>();
    for (int i = 0; i < batchSize; i++) {
        // We only generate a remove if we have something to remove.
        boolean remove = removalCandidates.size() > 0 && (context.random.nextDouble() < REMOVE_FRACTION);
        if (remove) {
            val key = removalCandidates.get(context.random.nextInt(removalCandidates.size()));
            toRemove.add(key);
            removalCandidates.remove(key);
        } else {
            // Generate a new Table Entry.
            BufferView key = createRandomKey(context);
            BufferView value = createRandomData(context.random.nextInt(MAX_VALUE_LENGTH), context);
            toUpdate.put(key, value);
            removalCandidates.add(key);
        }
    }
    expectedEntries.putAll(toUpdate);
    expectedEntries.keySet().removeAll(toRemove);
    // Keep track of expected metrics.
    int totalUpdateCount = toUpdate.size();
    int totalRemoveCount = toRemove.size();
    if (previous != null) {
        totalUpdateCount += previous.totalUpdatesCount;
        totalRemoveCount += previous.totalRemoveCount;
    }
    return new TestBatchData(toUpdate, toRemove, expectedEntries, totalUpdateCount, totalRemoveCount);
}
Also used : lombok.val(lombok.val) BufferView(io.pravega.common.util.BufferView) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList)

Example 50 with BufferView

use of io.pravega.common.util.BufferView in project pravega by pravega.

the class TableServiceTests method check.

private void check(HashMap<BufferView, EntryData> keyInfo, TableStore tableStore) throws Exception {
    val bySegment = keyInfo.entrySet().stream().collect(Collectors.groupingBy(e -> e.getValue().segmentName));
    // Check inexistent keys.
    val searchFutures = new ArrayList<CompletableFuture<List<TableEntry>>>();
    val iteratorFutures = new ArrayList<CompletableFuture<List<TableEntry>>>();
    // Delta Iteration does not support fixed-key-length TableSegments.
    val unsortedIteratorFutures = new ArrayList<CompletableFuture<List<TableEntry>>>();
    val offsetIteratorFutures = new ArrayList<CompletableFuture<List<IteratorItem<TableEntry>>>>();
    val expectedResult = new ArrayList<Map.Entry<BufferView, EntryData>>();
    for (val e : bySegment.entrySet()) {
        String segmentName = e.getKey();
        boolean fixedKeyLength = isFixedKeyLength(segmentName);
        val info = tableStore.getInfo(segmentName, TIMEOUT).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
        Assert.assertEquals(segmentName, info.getName());
        AssertExtensions.assertGreaterThan("Unexpected length for " + segmentName, 0, info.getLength());
        val expectedKeyLength = isFixedKeyLength(segmentName) ? getFixedKeyLength(segmentName) : 0;
        Assert.assertEquals("Unexpected key length for " + segmentName, expectedKeyLength, info.getKeyLength());
        Assert.assertEquals(fixedKeyLength, info.getType().isFixedKeyLengthTableSegment());
        val keys = new ArrayList<BufferView>();
        for (val se : e.getValue()) {
            keys.add(se.getKey());
            expectedResult.add(se);
        }
        searchFutures.add(tableStore.get(segmentName, keys, TIMEOUT));
        CompletableFuture<List<TableEntry>> entryIteratorFuture = tableStore.entryIterator(segmentName, IteratorArgs.builder().fetchTimeout(TIMEOUT).build()).thenCompose(ei -> {
            val result = new ArrayList<TableEntry>();
            return ei.forEachRemaining(i -> result.addAll(i.getEntries()), executorService()).thenApply(v -> {
                if (fixedKeyLength) {
                    checkSortedOrder(result);
                }
                return result;
            });
        });
        iteratorFutures.add(entryIteratorFuture);
        if (!fixedKeyLength) {
            unsortedIteratorFutures.add(entryIteratorFuture);
            // For simplicity, always start from beginning of TableSegment.
            offsetIteratorFutures.add(tableStore.entryDeltaIterator(segmentName, 0L, TIMEOUT).thenCompose(ei -> {
                val result = new ArrayList<IteratorItem<TableEntry>>();
                return ei.forEachRemaining(result::add, executorService()).thenApply(v -> result);
            }));
        }
    }
    // Check search results.
    val actualResults = Futures.allOfWithResults(searchFutures).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS).stream().flatMap(List::stream).collect(Collectors.toList());
    Assert.assertEquals("Unexpected number of search results.", expectedResult.size(), actualResults.size());
    for (int i = 0; i < expectedResult.size(); i++) {
        val expectedKey = expectedResult.get(i).getKey();
        val expectedEntry = expectedResult.get(i).getValue();
        val actual = actualResults.get(i);
        if (expectedEntry.isDeleted()) {
            // Deleted keys will be returned as nulls.
            if (actual != null) {
                val r2 = tableStore.get(expectedEntry.segmentName, Collections.singletonList(expectedKey), TIMEOUT).join();
            }
            Assert.assertNull("Not expecting a value for a deleted Key ", actual);
        } else {
            Assert.assertEquals("Unexpected value for non-deleted Key.", expectedEntry.getValue(), actual.getValue());
            Assert.assertEquals("Unexpected key for non-deleted Key.", expectedKey, actual.getKey().getKey());
            Assert.assertEquals("Unexpected TableKey.Version for non-deleted Key.", expectedEntry.getVersion(), actual.getKey().getVersion());
        }
    }
    // Check iterator results. We sort it (and actualResults) by Version/Offset to ease the comparison.
    val actualIteratorResults = Futures.allOfWithResults(iteratorFutures).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS).stream().flatMap(List::stream).sorted(Comparator.comparingLong(e -> e.getKey().getVersion())).collect(Collectors.toList());
    val expectedIteratorResults = actualResults.stream().filter(Objects::nonNull).sorted(Comparator.comparingLong(e -> e.getKey().getVersion())).collect(Collectors.toList());
    // These lists are used to compare non-delta based iteration with delta based iteration.
    val actualUnsortedIteratorResults = Futures.allOfWithResults(unsortedIteratorFutures).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS).stream().flatMap(List::stream).sorted(Comparator.comparingLong(e -> e.getKey().getVersion())).collect(Collectors.toList());
    val expectedUnsortedIteratorResults = actualUnsortedIteratorResults.stream().filter(Objects::nonNull).sorted(Comparator.comparingLong(e -> e.getKey().getVersion())).collect(Collectors.toList());
    val actualOffsetIteratorList = Futures.allOfWithResults(offsetIteratorFutures).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS).stream().flatMap(List::stream).collect(Collectors.toList());
    val actualOffsetIteratorResults = processDeltaIteratorItems(actualOffsetIteratorList).stream().sorted(Comparator.comparingLong(e -> e.getKey().getVersion())).collect(Collectors.toList());
    AssertExtensions.assertListEquals("Unexpected result from entryIterator().", expectedIteratorResults, actualIteratorResults, TableEntry::equals);
    for (val entry : expectedUnsortedIteratorResults) {
        Assert.assertNotNull("Missing expected TableEntry from deltaEntryIterator()", actualOffsetIteratorResults.contains(entry));
    }
}
Also used : lombok.val(lombok.val) BufferViewComparator(io.pravega.common.util.BufferViewComparator) TableSegmentConfig(io.pravega.segmentstore.contracts.tables.TableSegmentConfig) WriterConfig(io.pravega.segmentstore.server.writer.WriterConfig) TableStore(io.pravega.segmentstore.contracts.tables.TableStore) AssertExtensions(io.pravega.test.common.AssertExtensions) RequiredArgsConstructor(lombok.RequiredArgsConstructor) ServiceConfig(io.pravega.segmentstore.server.store.ServiceConfig) HashMap(java.util.HashMap) Random(java.util.Random) CompletableFuture(java.util.concurrent.CompletableFuture) ServiceBuilderConfig(io.pravega.segmentstore.server.store.ServiceBuilderConfig) AtomicReference(java.util.concurrent.atomic.AtomicReference) IteratorArgs(io.pravega.segmentstore.contracts.tables.IteratorArgs) ArrayList(java.util.ArrayList) SegmentType(io.pravega.segmentstore.contracts.SegmentType) ServiceBuilder(io.pravega.segmentstore.server.store.ServiceBuilder) IteratorItem(io.pravega.segmentstore.contracts.tables.IteratorItem) BufferView(io.pravega.common.util.BufferView) InMemoryStorageFactory(io.pravega.segmentstore.storage.mocks.InMemoryStorageFactory) Duration(java.time.Duration) Map(java.util.Map) After(org.junit.After) ContainerConfig(io.pravega.segmentstore.server.containers.ContainerConfig) ReadIndexConfig(io.pravega.segmentstore.server.reading.ReadIndexConfig) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) Timeout(org.junit.rules.Timeout) InMemoryDurableDataLogFactory(io.pravega.segmentstore.storage.mocks.InMemoryDurableDataLogFactory) StreamSegmentStore(io.pravega.segmentstore.contracts.StreamSegmentStore) Before(org.junit.Before) TableKey(io.pravega.segmentstore.contracts.tables.TableKey) DurableLogConfig(io.pravega.segmentstore.server.logs.DurableLogConfig) lombok.val(lombok.val) Test(org.junit.Test) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) Rule(org.junit.Rule) ByteArraySegment(io.pravega.common.util.ByteArraySegment) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) Comparator(java.util.Comparator) Assert(org.junit.Assert) TableEntry(io.pravega.segmentstore.contracts.tables.TableEntry) Collections(java.util.Collections) Futures(io.pravega.common.concurrent.Futures) ArrayList(java.util.ArrayList) TableEntry(io.pravega.segmentstore.contracts.tables.TableEntry) BufferView(io.pravega.common.util.BufferView) IteratorItem(io.pravega.segmentstore.contracts.tables.IteratorItem) Objects(java.util.Objects) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

BufferView (io.pravega.common.util.BufferView)77 ArrayList (java.util.ArrayList)49 lombok.val (lombok.val)49 ByteArraySegment (io.pravega.common.util.ByteArraySegment)44 Cleanup (lombok.Cleanup)42 Duration (java.time.Duration)39 Test (org.junit.Test)39 List (java.util.List)37 CompletableFuture (java.util.concurrent.CompletableFuture)34 AssertExtensions (io.pravega.test.common.AssertExtensions)29 HashMap (java.util.HashMap)29 Assert (org.junit.Assert)29 ThreadPooledTestSuite (io.pravega.test.common.ThreadPooledTestSuite)28 TimeUnit (java.util.concurrent.TimeUnit)28 AtomicReference (java.util.concurrent.atomic.AtomicReference)26 Collectors (java.util.stream.Collectors)26 AtomicLong (java.util.concurrent.atomic.AtomicLong)25 Exceptions (io.pravega.common.Exceptions)24 TableEntry (io.pravega.segmentstore.contracts.tables.TableEntry)24 Map (java.util.Map)22