Search in sources :

Example 16 with ScanProperties

use of com.apple.foundationdb.record.ScanProperties in project fdb-record-layer by FoundationDB.

the class FDBRecordStoreIndexTest method testIndexMissingValidation.

@Test
public void testIndexMissingValidation() throws Exception {
    final int nRecords = 10;
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context);
        for (int i = 0; i < nRecords; i++) {
            TestRecords1Proto.MySimpleRecord.Builder recBuilder = TestRecords1Proto.MySimpleRecord.newBuilder();
            recBuilder.setRecNo(i);
            recBuilder.setStrValueIndexed(Integer.toString(i));
            // nRecords is not larger than 10, so the indexes (sorted by the string version of recNo) are in the
            // same order as the records. This can make the test easy.
            recordStore.saveRecord(recBuilder.build());
        }
        commit(context);
    }
    // Delete the indexes of some records.
    Set<InvalidIndexEntry> expectedInvalidEntries = new HashSet<>();
    try (FDBRecordContext context = openContext()) {
        final Index index = recordStore.getRecordMetaData().getIndex("MySimpleRecord$str_value_indexed");
        openSimpleRecordStore(context);
        List<FDBStoredRecord<Message>> savedRecords = recordStore.scanRecords(TupleRange.ALL, null, ScanProperties.FORWARD_SCAN).asList().get();
        List<IndexEntry> indexEntries = recordStore.scanIndex(index, IndexScanType.BY_VALUE, TupleRange.ALL, null, ScanProperties.FORWARD_SCAN).asList().get();
        for (int i = 0; i < nRecords; i += 2) {
            IndexEntry indexEntry = indexEntries.get(i);
            FDBStoredRecord<Message> record = savedRecords.get(i);
            final Tuple valueKey = indexEntry.getKey();
            final Tuple entryKey = indexEntryKey(index, valueKey, record.getPrimaryKey());
            final byte[] keyBytes = recordStore.indexSubspace(index).pack(valueKey);
            byte[] v0 = recordStore.getContext().ensureActive().get(keyBytes).get();
            recordStore.getContext().ensureActive().clear(keyBytes);
            byte[] v = recordStore.getContext().ensureActive().get(keyBytes).get();
            expectedInvalidEntries.add(InvalidIndexEntry.newMissing(indexEntry, record));
        }
        commit(context);
    }
    try (FDBDatabaseRunner runner = fdb.newRunner()) {
        AtomicInteger generatorCount = new AtomicInteger();
        // Set a scanned records limit to mock when the NoNextReason is out of band.
        RecordCursorIterator<InvalidIndexEntry> cursor = new AutoContinuingCursor<>(runner, (context, continuation) -> new LazyCursor<>(FDBRecordStore.newBuilder().setContext(context).setKeySpacePath(path).setMetaDataProvider(simpleMetaData(NO_HOOK)).openAsync().thenApply(currentRecordStore -> {
            generatorCount.getAndIncrement();
            final Index index = currentRecordStore.getRecordMetaData().getIndex("MySimpleRecord$str_value_indexed");
            ScanProperties scanProperties = new ScanProperties(ExecuteProperties.newBuilder().setReturnedRowLimit(Integer.MAX_VALUE).setIsolationLevel(IsolationLevel.SNAPSHOT).setScannedRecordsLimit(4).build());
            return currentRecordStore.getIndexMaintainer(index).validateEntries(continuation, scanProperties);
        }))).asIterator();
        Set<InvalidIndexEntry> results = new HashSet<>();
        cursor.forEachRemaining(results::add);
        assertEquals(expectedInvalidEntries, results);
        // The number of scans is about the number of index entries (orphan validation) plus the number of records
        // (missing validation).
        assertThat(generatorCount.get(), greaterThanOrEqualTo((5 + 10) / 4));
    }
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) IndexScanType(com.apple.foundationdb.record.IndexScanType) Pair(org.apache.commons.lang3.tuple.Pair) FDBError(com.apple.foundationdb.FDBError) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) RecordIndexUniquenessViolation(com.apple.foundationdb.record.RecordIndexUniquenessViolation) Expressions.concat(com.apple.foundationdb.record.metadata.Key.Expressions.concat) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) Tag(org.junit.jupiter.api.Tag) Query(com.apple.foundationdb.record.query.expressions.Query) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) IndexOptions(com.apple.foundationdb.record.metadata.IndexOptions) Set(java.util.Set) FanType(com.apple.foundationdb.record.metadata.expressions.KeyExpression.FanType) TupleRange(com.apple.foundationdb.record.TupleRange) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) RecordMetaDataProvider(com.apple.foundationdb.record.RecordMetaDataProvider) RecordStoreState(com.apple.foundationdb.record.RecordStoreState) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) InvalidIndexEntry(com.apple.foundationdb.record.provider.foundationdb.indexes.InvalidIndexEntry) AutoContinuingCursor(com.apple.foundationdb.record.cursors.AutoContinuingCursor) Matchers.is(org.hamcrest.Matchers.is) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) Assertions.fail(org.junit.jupiter.api.Assertions.fail) FunctionNames(com.apple.foundationdb.record.FunctionNames) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) ArrayList(java.util.ArrayList) Strings(com.google.common.base.Strings) CloseableAsyncIterator(com.apple.foundationdb.async.CloseableAsyncIterator) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) FDBRecordStoreBase.indexEntryKey(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase.indexEntryKey) Nullable(javax.annotation.Nullable) Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) IsolationLevel(com.apple.foundationdb.record.IsolationLevel) Tags(com.apple.test.Tags) TestRecords1EvolvedProto(com.apple.foundationdb.record.TestRecords1EvolvedProto) ExecutionException(java.util.concurrent.ExecutionException) Assertions.assertArrayEquals(org.junit.jupiter.api.Assertions.assertArrayEquals) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Index(com.apple.foundationdb.record.metadata.Index) FDBException(com.apple.foundationdb.FDBException) ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) IndexEntry(com.apple.foundationdb.record.IndexEntry) StoreTimer(com.apple.foundationdb.record.provider.common.StoreTimer) LoggerFactory(org.slf4j.LoggerFactory) Assertions.assertNotEquals(org.junit.jupiter.api.Assertions.assertNotEquals) Random(java.util.Random) Tuple(com.apple.foundationdb.tuple.Tuple) Range(com.apple.foundationdb.Range) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Expressions.concatenateFields(com.apple.foundationdb.record.metadata.Key.Expressions.concatenateFields) ImmutableSet(com.google.common.collect.ImmutableSet) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) ImmutableMap(com.google.common.collect.ImmutableMap) Matchers.lessThanOrEqualTo(org.hamcrest.Matchers.lessThanOrEqualTo) Collection(java.util.Collection) CompletionException(java.util.concurrent.CompletionException) IndexQueryabilityFilter(com.apple.foundationdb.record.query.IndexQueryabilityFilter) TypeSafeMatcher(org.hamcrest.TypeSafeMatcher) Collectors(java.util.stream.Collectors) Test(org.junit.jupiter.api.Test) List(java.util.List) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) Matchers.equalTo(org.hamcrest.Matchers.equalTo) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) Optional(java.util.Optional) TestNoIndexesProto(com.apple.foundationdb.record.TestNoIndexesProto) LazyCursor(com.apple.foundationdb.record.cursors.LazyCursor) EnumSource(org.junit.jupiter.params.provider.EnumSource) CompletableFuture(java.util.concurrent.CompletableFuture) Iterators(com.google.common.collect.Iterators) Key(com.apple.foundationdb.record.metadata.Key) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) HashSet(java.util.HashSet) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) ScanProperties(com.apple.foundationdb.record.ScanProperties) RecordCursorIterator(com.apple.foundationdb.record.RecordCursorIterator) BooleanSource(com.apple.test.BooleanSource) Nonnull(javax.annotation.Nonnull) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) Matchers.hasEntry(org.hamcrest.Matchers.hasEntry) Description(org.hamcrest.Description) Matchers.oneOf(org.hamcrest.Matchers.oneOf) Logger(org.slf4j.Logger) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) IndexState(com.apple.foundationdb.record.IndexState) TestRecordsIndexFilteringProto(com.apple.foundationdb.record.TestRecordsIndexFilteringProto) Message(com.google.protobuf.Message) Collections(java.util.Collections) Message(com.google.protobuf.Message) InvalidIndexEntry(com.apple.foundationdb.record.provider.foundationdb.indexes.InvalidIndexEntry) IndexEntry(com.apple.foundationdb.record.IndexEntry) Index(com.apple.foundationdb.record.metadata.Index) LazyCursor(com.apple.foundationdb.record.cursors.LazyCursor) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ScanProperties(com.apple.foundationdb.record.ScanProperties) InvalidIndexEntry(com.apple.foundationdb.record.provider.foundationdb.indexes.InvalidIndexEntry) Tuple(com.apple.foundationdb.tuple.Tuple) HashSet(java.util.HashSet) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Test(org.junit.jupiter.api.Test)

Example 17 with ScanProperties

use of com.apple.foundationdb.record.ScanProperties in project fdb-record-layer by FoundationDB.

the class TextIndexTest method scanWithSkip.

public void scanWithSkip(@Nonnull Index index, @Nonnull String token, int skip, int limit, boolean reverse) throws Exception {
    try (FDBRecordContext context = openContext()) {
        openRecordStore(context);
        final List<IndexEntry> fullResults = scanIndex(recordStore, index, TupleRange.allOf(Tuple.from(token)));
        validateSorted(fullResults);
        final ScanProperties scanProperties = ExecuteProperties.newBuilder().setReturnedRowLimit(limit).setSkip(skip).build().asScanProperties(reverse);
        final RecordCursor<IndexEntry> cursor = recordStore.scanIndex(index, BY_TEXT_TOKEN, TupleRange.allOf(Tuple.from(token)), null, scanProperties);
        List<IndexEntry> scanResults = cursor.asList().get();
        RecordCursorResult<IndexEntry> noNextResult = cursor.getNext();
        assertThat(noNextResult.hasNext(), is(false));
        assertEquals((limit != ReadTransaction.ROW_LIMIT_UNLIMITED && scanResults.size() == limit) ? RETURN_LIMIT_REACHED : SOURCE_EXHAUSTED, noNextResult.getNoNextReason());
        List<IndexEntry> expectedResults;
        if (reverse) {
            scanResults = new ArrayList<>(scanResults);
            Collections.reverse(scanResults);
            expectedResults = fullResults.subList((limit == ReadTransaction.ROW_LIMIT_UNLIMITED || limit == Integer.MAX_VALUE) ? 0 : Math.max(0, fullResults.size() - skip - limit), Math.max(0, fullResults.size() - skip));
        } else {
            expectedResults = fullResults.subList(Math.min(fullResults.size(), skip), (limit == ReadTransaction.ROW_LIMIT_UNLIMITED || limit == Integer.MAX_VALUE) ? fullResults.size() : Math.min(fullResults.size(), skip + limit));
        }
        assertEquals(expectedResults, scanResults);
    }
}
Also used : FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) ScanProperties(com.apple.foundationdb.record.ScanProperties) IndexEntry(com.apple.foundationdb.record.IndexEntry)

Example 18 with ScanProperties

use of com.apple.foundationdb.record.ScanProperties in project fdb-record-layer by FoundationDB.

the class TextIndexTest method scanMultipleWithScanRecordLimits.

private void scanMultipleWithScanRecordLimits(@Nonnull Index index, @Nonnull List<String> tokens, int scanRecordLimit, boolean reverse) throws Exception {
    try (FDBRecordContext context = openContext()) {
        openRecordStore(context);
        ScanProperties scanProperties = ExecuteProperties.newBuilder().setScannedRecordsLimit(scanRecordLimit).build().asScanProperties(reverse);
        List<RecordCursor<IndexEntry>> cursors = tokens.stream().map(token -> recordStore.scanIndex(index, BY_TEXT_TOKEN, TupleRange.allOf(Tuple.from(token)), null, scanProperties)).collect(Collectors.toList());
        int cursorIndex = 0;
        int retrieved = 0;
        while (!cursors.isEmpty()) {
            RecordCursor<IndexEntry> cursor = cursors.get(cursorIndex);
            RecordCursorResult<IndexEntry> result = cursor.getNext();
            if (result.hasNext()) {
                retrieved++;
                cursorIndex = (cursorIndex + 1) % cursors.size();
            } else {
                if (!result.getNoNextReason().isSourceExhausted()) {
                    assertEquals(SCAN_LIMIT_REACHED, result.getNoNextReason());
                }
                cursors.remove(cursorIndex);
                if (cursorIndex == cursors.size()) {
                    cursorIndex = 0;
                }
            }
        }
        // With the order that they are retrieved, the maximum value is the scanRecordLimit
        // or the number of tokens.
        assertThat(retrieved, lessThanOrEqualTo(Math.max(scanRecordLimit, tokens.size())));
    }
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) BY_GROUP(com.apple.foundationdb.record.IndexScanType.BY_GROUP) Matchers.not(org.hamcrest.Matchers.not) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) TextTokenizerFactory(com.apple.foundationdb.record.provider.common.text.TextTokenizerFactory) ComplexDocument(com.apple.foundationdb.record.TestRecordsTextProto.ComplexDocument) Subspace(com.apple.foundationdb.subspace.Subspace) TextSamples(com.apple.foundationdb.record.provider.common.text.TextSamples) RecordCursorResult(com.apple.foundationdb.record.RecordCursorResult) Pair(org.apache.commons.lang3.tuple.Pair) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) COMPLEX_DOC(com.apple.foundationdb.record.provider.foundationdb.indexes.TextIndexTestUtils.COMPLEX_DOC) VersionKeyExpression(com.apple.foundationdb.record.metadata.expressions.VersionKeyExpression) Map(java.util.Map) Expressions.concat(com.apple.foundationdb.record.metadata.Key.Expressions.concat) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) Tag(org.junit.jupiter.api.Tag) Query(com.apple.foundationdb.record.query.expressions.Query) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) IndexOptions(com.apple.foundationdb.record.metadata.IndexOptions) Matchers.notNullValue(org.hamcrest.Matchers.notNullValue) Matchers.allOf(org.hamcrest.Matchers.allOf) Set(java.util.Set) PlanMatchers.textComparison(com.apple.foundationdb.record.query.plan.match.PlanMatchers.textComparison) FanType(com.apple.foundationdb.record.metadata.expressions.KeyExpression.FanType) Arguments(org.junit.jupiter.params.provider.Arguments) BY_VALUE(com.apple.foundationdb.record.IndexScanType.BY_VALUE) TupleRange(com.apple.foundationdb.record.TupleRange) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) TestRecordsTextProto(com.apple.foundationdb.record.TestRecordsTextProto) Stream(java.util.stream.Stream) PlanMatchers.indexName(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexName) Matchers.anything(org.hamcrest.Matchers.anything) Matchers.contains(org.hamcrest.Matchers.contains) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) Matchers.is(org.hamcrest.Matchers.is) PlanMatchers.typeFilter(com.apple.foundationdb.record.query.plan.match.PlanMatchers.typeFilter) Matchers.containsString(org.hamcrest.Matchers.containsString) FDBIndexedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBIndexedRecord) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) PlanMatchers.fetch(com.apple.foundationdb.record.query.plan.match.PlanMatchers.fetch) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) ComponentWithComparison(com.apple.foundationdb.record.query.expressions.ComponentWithComparison) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) ArrayList(java.util.ArrayList) PlanMatchers(com.apple.foundationdb.record.query.plan.match.PlanMatchers) BunchedMap(com.apple.foundationdb.map.BunchedMap) TestLogMessageKeys(com.apple.foundationdb.record.logging.TestLogMessageKeys) LoggableException(com.apple.foundationdb.util.LoggableException) Matchers.lessThan(org.hamcrest.Matchers.lessThan) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Nullable(javax.annotation.Nullable) FDBStoredRecord(com.apple.foundationdb.record.provider.foundationdb.FDBStoredRecord) FieldWithComparison(com.apple.foundationdb.record.query.expressions.FieldWithComparison) Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) SOURCE_EXHAUSTED(com.apple.foundationdb.record.RecordCursor.NoNextReason.SOURCE_EXHAUSTED) Tags(com.apple.test.Tags) SCAN_LIMIT_REACHED(com.apple.foundationdb.record.RecordCursor.NoNextReason.SCAN_LIMIT_REACHED) OrComponent(com.apple.foundationdb.record.query.expressions.OrComponent) BunchedMapScanEntry(com.apple.foundationdb.map.BunchedMapScanEntry) FDBRecordStoreTestBase(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreTestBase) ExecutionException(java.util.concurrent.ExecutionException) AndOrComponent(com.apple.foundationdb.record.query.expressions.AndOrComponent) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Index(com.apple.foundationdb.record.metadata.Index) Matcher(org.hamcrest.Matcher) PlanMatchers.unorderedUnion(com.apple.foundationdb.record.query.plan.match.PlanMatchers.unorderedUnion) TextIndexBunchedSerializerTest.entryOf(com.apple.foundationdb.record.provider.foundationdb.indexes.TextIndexBunchedSerializerTest.entryOf) IndexEntry(com.apple.foundationdb.record.IndexEntry) PlanMatchers.groupingBounds(com.apple.foundationdb.record.query.plan.match.PlanMatchers.groupingBounds) StoreTimer(com.apple.foundationdb.record.provider.common.StoreTimer) LoggerFactory(org.slf4j.LoggerFactory) BY_RANK(com.apple.foundationdb.record.IndexScanType.BY_RANK) PrefixTextTokenizer(com.apple.foundationdb.record.provider.common.text.PrefixTextTokenizer) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Random(java.util.Random) SubspaceSplitter(com.apple.foundationdb.map.SubspaceSplitter) PlanMatchers.bounds(com.apple.foundationdb.record.query.plan.match.PlanMatchers.bounds) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) Tuple(com.apple.foundationdb.tuple.Tuple) KeyValueLogMessage(com.apple.foundationdb.record.logging.KeyValueLogMessage) PlanMatchers.textIndexScan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.textIndexScan) TextTokenizerRegistryImpl(com.apple.foundationdb.record.provider.common.text.TextTokenizerRegistryImpl) Expressions.concatenateFields(com.apple.foundationdb.record.metadata.Key.Expressions.concatenateFields) RETURN_LIMIT_REACHED(com.apple.foundationdb.record.RecordCursor.NoNextReason.RETURN_LIMIT_REACHED) FDBExceptions(com.apple.foundationdb.record.provider.foundationdb.FDBExceptions) MethodSource(org.junit.jupiter.params.provider.MethodSource) PlanMatchers.coveringIndexScan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.coveringIndexScan) ImmutableSet(com.google.common.collect.ImmutableSet) KeyValue(com.apple.foundationdb.KeyValue) SimpleDocument(com.apple.foundationdb.record.TestRecordsTextProto.SimpleDocument) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) ImmutableMap(com.google.common.collect.ImmutableMap) Matchers.lessThanOrEqualTo(org.hamcrest.Matchers.lessThanOrEqualTo) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) Collectors(java.util.stream.Collectors) Test(org.junit.jupiter.api.Test) TextTokenizer(com.apple.foundationdb.record.provider.common.text.TextTokenizer) PlanMatchers.hasTupleString(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasTupleString) List(java.util.List) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Matchers.equalTo(org.hamcrest.Matchers.equalTo) MapDocument(com.apple.foundationdb.record.TestRecordsTextProto.MapDocument) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) Matchers.anyOf(org.hamcrest.Matchers.anyOf) IntStream(java.util.stream.IntStream) PlanMatchers.primaryKeyDistinct(com.apple.foundationdb.record.query.plan.match.PlanMatchers.primaryKeyDistinct) Descriptors(com.google.protobuf.Descriptors) CompletableFuture(java.util.concurrent.CompletableFuture) BooleanNormalizer(com.apple.foundationdb.record.query.plan.planning.BooleanNormalizer) PlanHashable(com.apple.foundationdb.record.PlanHashable) PlanMatchers.filter(com.apple.foundationdb.record.query.plan.match.PlanMatchers.filter) HashSet(java.util.HashSet) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) ScanProperties(com.apple.foundationdb.record.ScanProperties) RecordCursorIterator(com.apple.foundationdb.record.RecordCursorIterator) DefaultTextTokenizer(com.apple.foundationdb.record.provider.common.text.DefaultTextTokenizer) BY_TEXT_TOKEN(com.apple.foundationdb.record.IndexScanType.BY_TEXT_TOKEN) BunchedMapMultiIterator(com.apple.foundationdb.map.BunchedMapMultiIterator) Nonnull(javax.annotation.Nonnull) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) SIMPLE_DOC(com.apple.foundationdb.record.provider.foundationdb.indexes.TextIndexTestUtils.SIMPLE_DOC) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) BY_TIME_WINDOW(com.apple.foundationdb.record.IndexScanType.BY_TIME_WINDOW) FilteringTextTokenizer(com.apple.foundationdb.record.provider.common.text.FilteringTextTokenizer) ReadTransaction(com.apple.foundationdb.ReadTransaction) Normalizer(java.text.Normalizer) Matchers.any(org.hamcrest.Matchers.any) TimeUnit(java.util.concurrent.TimeUnit) DefaultTextTokenizerFactory(com.apple.foundationdb.record.provider.common.text.DefaultTextTokenizerFactory) PlanMatchers.unbounded(com.apple.foundationdb.record.query.plan.match.PlanMatchers.unbounded) FDBDatabaseFactory(com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseFactory) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) PlanMatchers.descendant(com.apple.foundationdb.record.query.plan.match.PlanMatchers.descendant) Comparator(java.util.Comparator) Collections(java.util.Collections) AllSuffixesTextTokenizer(com.apple.foundationdb.record.provider.common.text.AllSuffixesTextTokenizer) RecordCursor(com.apple.foundationdb.record.RecordCursor) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) ScanProperties(com.apple.foundationdb.record.ScanProperties) IndexEntry(com.apple.foundationdb.record.IndexEntry)

Example 19 with ScanProperties

use of com.apple.foundationdb.record.ScanProperties in project fdb-record-layer by FoundationDB.

the class TextIndexTest method scanIndex.

@Nonnull
private static List<IndexEntry> scanIndex(@Nonnull FDBRecordStore store, @Nonnull Index index, @Nonnull TupleRange range) throws ExecutionException, InterruptedException {
    List<IndexEntry> results = scanIndex(store, index, range, ScanProperties.FORWARD_SCAN);
    validateSorted(results);
    List<IndexEntry> backwardResults = new ArrayList<>(scanIndex(store, index, range, ScanProperties.REVERSE_SCAN));
    Collections.reverse(backwardResults);
    assertEquals(results, backwardResults);
    // Validate that
    final int limit = 3;
    for (int i = 0; i < 8; i++) {
        ExecuteProperties.Builder propertiesBuilder = ExecuteProperties.newBuilder();
        if (i < 4) {
            propertiesBuilder.setReturnedRowLimit(limit);
        } else {
            propertiesBuilder.setScannedRecordsLimit(limit);
        }
        List<IndexEntry> paginatedResults = new ArrayList<>(results.size());
        boolean done = false;
        byte[] continuation = null;
        do {
            if (i >= 2 && i < 4) {
                // Use skip instead of continuation to achieve the same results.
                continuation = null;
                propertiesBuilder.setSkip(paginatedResults.size());
            }
            ScanProperties scanProperties = propertiesBuilder.build().asScanProperties(i % 2 == 0);
            int retrieved = 0;
            RecordCursorIterator<IndexEntry> cursor = store.scanIndex(index, BY_TEXT_TOKEN, range, continuation, scanProperties).asIterator();
            while (cursor.hasNext()) {
                paginatedResults.add(cursor.next());
                retrieved++;
            }
            if (done) {
                assertEquals(0, retrieved);
                assertNull(cursor.getContinuation());
            }
            if (retrieved < limit) {
                assertEquals(SOURCE_EXHAUSTED, cursor.getNoNextReason());
            } else {
                assertEquals(limit, retrieved);
                assertEquals(i < 4 ? RETURN_LIMIT_REACHED : SCAN_LIMIT_REACHED, cursor.getNoNextReason());
            }
            done = cursor.getNoNextReason().isSourceExhausted();
            continuation = cursor.getContinuation();
        } while (continuation != null);
        if (i % 2 == 0) {
            Collections.reverse(paginatedResults);
        }
        assertEquals(results, paginatedResults);
    }
    return results;
}
Also used : ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) ScanProperties(com.apple.foundationdb.record.ScanProperties) ArrayList(java.util.ArrayList) IndexEntry(com.apple.foundationdb.record.IndexEntry) Nonnull(javax.annotation.Nonnull)

Example 20 with ScanProperties

use of com.apple.foundationdb.record.ScanProperties in project fdb-record-layer by FoundationDB.

the class UnionIntersectionTest method indexScansByPrimaryKey.

/**
 * Create cursors that correspond to union or intersection query and validate that using the custom comparison
 * key works.
 */
@Test
public void indexScansByPrimaryKey() throws Exception {
    final ScanProperties scanProperties = ScanProperties.FORWARD_SCAN;
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context);
        final Index strValueIndex = recordStore.getRecordMetaData().getIndex("MySimpleRecord$str_value_indexed");
        final Index numValue3Index = recordStore.getRecordMetaData().getIndex("MySimpleRecord$num_value_3_indexed");
        List<Long> recNos = IntersectionCursor.create((IndexEntry entry) -> TupleHelpers.subTuple(entry.getKey(), 1, entry.getKey().size()).getItems(), false, (byte[] leftContinuation) -> recordStore.scanIndex(strValueIndex, IndexScanType.BY_VALUE, TupleRange.allOf(Tuple.from("even")), leftContinuation, scanProperties), (byte[] rightContinuation) -> recordStore.scanIndex(numValue3Index, IndexScanType.BY_VALUE, TupleRange.allOf(Tuple.from(1)), rightContinuation, scanProperties), null, recordStore.getTimer()).mapPipelined(indexEntry -> recordStore.loadRecordAsync(strValueIndex.getEntryPrimaryKey(indexEntry.getKey())), recordStore.getPipelineSize(PipelineOperation.INDEX_TO_RECORD)).map(this::storedRecordRecNo).asList().get();
        assertEquals(LongStream.range(0, 100).filter(i -> i % 2 == 0).filter(i -> i % 3 != 0).boxed().collect(Collectors.toList()), recNos);
        assertDiscardedAtMost(50, context);
        recNos = UnionCursor.create((IndexEntry entry) -> TupleHelpers.subTuple(entry.getKey(), 1, entry.getKey().size()).getItems(), false, (byte[] leftContinuation) -> recordStore.scanIndex(strValueIndex, IndexScanType.BY_VALUE, TupleRange.allOf(Tuple.from("even")), leftContinuation, scanProperties), (byte[] rightContinuation) -> recordStore.scanIndex(numValue3Index, IndexScanType.BY_VALUE, TupleRange.allOf(Tuple.from(1)), rightContinuation, scanProperties), null, recordStore.getTimer()).mapPipelined(indexEntry -> recordStore.loadRecordAsync(strValueIndex.getEntryPrimaryKey(indexEntry.getKey())), recordStore.getPipelineSize(PipelineOperation.INDEX_TO_RECORD)).map(this::storedRecordRecNo).asList().get();
        assertEquals(LongStream.range(0, 100).filter(i -> i % 2 == 0 || i % 3 != 0).boxed().collect(Collectors.toList()), recNos);
        assertDiscardedAtMost(83, context);
        commit(context);
    }
}
Also used : IndexEntry(com.apple.foundationdb.record.IndexEntry) BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) FDBRecord(com.apple.foundationdb.record.provider.foundationdb.FDBRecord) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Function(java.util.function.Function) ArrayList(java.util.ArrayList) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) IndexScanType(com.apple.foundationdb.record.IndexScanType) Tuple(com.apple.foundationdb.tuple.Tuple) RecordCursorResult(com.apple.foundationdb.record.RecordCursorResult) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) EndpointType(com.apple.foundationdb.record.EndpointType) ScanProperties(com.apple.foundationdb.record.ScanProperties) PipelineOperation(com.apple.foundationdb.record.PipelineOperation) RecordCursorIterator(com.apple.foundationdb.record.RecordCursorIterator) Tag(org.junit.jupiter.api.Tag) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) FDBStoredRecord(com.apple.foundationdb.record.provider.foundationdb.FDBStoredRecord) ValueSource(org.junit.jupiter.params.provider.ValueSource) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) LongStream(java.util.stream.LongStream) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) Tags(com.apple.test.Tags) ScanComparisons(com.apple.foundationdb.record.query.plan.ScanComparisons) Collectors(java.util.stream.Collectors) TupleRange(com.apple.foundationdb.record.TupleRange) FDBRecordStoreTestBase(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreTestBase) Test(org.junit.jupiter.api.Test) PrimitiveIterator(java.util.PrimitiveIterator) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) List(java.util.List) Index(com.apple.foundationdb.record.metadata.Index) TestHelpers.assertDiscardedAtMost(com.apple.foundationdb.record.TestHelpers.assertDiscardedAtMost) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) RecordCursorTest(com.apple.foundationdb.record.RecordCursorTest) Collections(java.util.Collections) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) ScanProperties(com.apple.foundationdb.record.ScanProperties) IndexEntry(com.apple.foundationdb.record.IndexEntry) Index(com.apple.foundationdb.record.metadata.Index) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) RecordCursorTest(com.apple.foundationdb.record.RecordCursorTest)

Aggregations

ScanProperties (com.apple.foundationdb.record.ScanProperties)54 ExecuteProperties (com.apple.foundationdb.record.ExecuteProperties)29 Nonnull (javax.annotation.Nonnull)29 Tuple (com.apple.foundationdb.tuple.Tuple)26 Message (com.google.protobuf.Message)24 Test (org.junit.jupiter.api.Test)24 RecordCursor (com.apple.foundationdb.record.RecordCursor)22 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)22 TupleRange (com.apple.foundationdb.record.TupleRange)21 List (java.util.List)21 ArrayList (java.util.ArrayList)20 IndexEntry (com.apple.foundationdb.record.IndexEntry)19 CompletableFuture (java.util.concurrent.CompletableFuture)19 Nullable (javax.annotation.Nullable)18 Index (com.apple.foundationdb.record.metadata.Index)17 AsyncUtil (com.apple.foundationdb.async.AsyncUtil)16 TupleHelpers (com.apple.foundationdb.tuple.TupleHelpers)16 LogMessageKeys (com.apple.foundationdb.record.logging.LogMessageKeys)15 Arrays (java.util.Arrays)15 Collectors (java.util.stream.Collectors)15