Search in sources :

Example 21 with IndexEntry

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

the class VersionIndexTest method assertMaxVersionsForGroups.

@SuppressWarnings("try")
private void assertMaxVersionsForGroups(@Nonnull SortedMap<Integer, FDBRecordVersion> groupsToVersions) {
    try (FDBRecordContext context = openContext(maxEverVersionWithGroupingHook)) {
        Index index = metaData.getIndex("max_ever_version_with_grouping");
        List<IndexEntry> entries = new ArrayList<>(groupsToVersions.size());
        for (Map.Entry<Integer, FDBRecordVersion> mapEntry : groupsToVersions.entrySet()) {
            entries.add(new IndexEntry(index, Key.Evaluated.scalar(mapEntry.getKey()), Key.Evaluated.scalar(mapEntry.getValue())));
        }
        assertMaxVersionEntries(index, entries);
    }
}
Also used : FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) ArrayList(java.util.ArrayList) IndexEntry(com.apple.foundationdb.record.IndexEntry) Index(com.apple.foundationdb.record.metadata.Index) Map(java.util.Map) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) FDBRecordVersion(com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion)

Example 22 with IndexEntry

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

the class VersionIndexTest method assertMaxVersionWithFunction.

@SuppressWarnings("try")
private void assertMaxVersionWithFunction(int controlColumn, @Nonnull FDBRecordVersion recordVersion) {
    try (FDBRecordContext context = openContext(maxEverVersionWithFunctionHook)) {
        Index index = metaData.getIndex("max_ever_version_with_function");
        IndexEntry entry = new IndexEntry(index, Key.Evaluated.EMPTY, Key.Evaluated.concatenate(controlColumn, recordVersion));
        assertMaxVersionEntries(index, Collections.singletonList(entry));
    }
}
Also used : FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) IndexEntry(com.apple.foundationdb.record.IndexEntry) Index(com.apple.foundationdb.record.metadata.Index)

Example 23 with IndexEntry

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

the class VersionIndexTest method enableRecordVersionsAfterTheFact.

@ParameterizedTest(name = "enableRecordVersionsAfterTheFact [formatVersion = {0}, splitLongRecords = {1}]")
@MethodSource("formatVersionArguments")
@SuppressWarnings("try")
public void enableRecordVersionsAfterTheFact(int testFormatVersion, boolean testSplitLongRecords) throws ExecutionException, InterruptedException {
    formatVersion = testFormatVersion;
    splitLongRecords = testSplitLongRecords;
    MySimpleRecord record1 = MySimpleRecord.newBuilder().setRecNo(871L).setNumValue2(871).build();
    MySimpleRecord record2 = MySimpleRecord.newBuilder().setRecNo(1415L).setNumValue2(1415).build();
    MySimpleRecord record3 = MySimpleRecord.newBuilder().setRecNo(3415L).setNumValue2(3415).build();
    Index globalCountIndex = new Index("globalCount", new GroupingKeyExpression(EmptyKeyExpression.EMPTY, 0), IndexTypes.COUNT);
    RecordMetaDataHook origHook = metaDataBuilder -> {
        noVersionHook.apply(metaDataBuilder);
        metaDataBuilder.addIndex((RecordTypeBuilder) null, globalCountIndex);
    };
    try (FDBRecordContext context = openContext(origHook)) {
        assertFalse(metaData.isStoreRecordVersions());
        recordStore.saveRecord(record1);
        recordStore.saveRecord(record2);
        recordStore.saveRecord(record3, null, FDBRecordStoreBase.VersionstampSaveBehavior.WITH_VERSION);
        context.commit();
    }
    try (FDBRecordContext context = openContext(metaDataBuilder -> {
        origHook.apply(metaDataBuilder);
        metaDataBuilder.setStoreRecordVersions(true);
        functionVersionHook.apply(metaDataBuilder);
    })) {
        assertTrue(metaData.isStoreRecordVersions());
        FDBStoredRecord<Message> storedRecord1 = recordStore.loadRecord(Tuple.from(871L));
        assertNotNull(storedRecord1);
        assertEquals(record1, storedRecord1.getRecord());
        assertFalse(storedRecord1.hasVersion());
        FDBStoredRecord<Message> storedRecord2 = recordStore.loadRecord(Tuple.from(1415L));
        assertNotNull(storedRecord2);
        assertEquals(record2, storedRecord2.getRecord());
        assertFalse(storedRecord2.hasVersion());
        FDBStoredRecord<Message> storedRecord3 = recordStore.loadRecord(Tuple.from(3415L));
        assertNotNull(storedRecord3);
        assertEquals(record3, storedRecord3.getRecord());
        assertTrue(storedRecord3.hasVersion());
        RecordCursor<IndexEntry> cursor = recordStore.scanIndex(metaData.getIndex("MySimpleRecord$maybeVersion"), IndexScanType.BY_VALUE, TupleRange.ALL, null, ScanProperties.FORWARD_SCAN);
        assertEquals(Arrays.asList(Tuple.from(null, 1415L), Tuple.from(FDBRecordVersion.MIN_VERSION.toVersionstamp(), 871L), Tuple.from(storedRecord3.getVersion().toVersionstamp(), 3415L)), cursor.map(IndexEntry::getKey).asList().get());
    }
}
Also used : MySimpleRecord(com.apple.foundationdb.record.TestRecords1Proto.MySimpleRecord) RecordMetaDataHook(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreTestBase.RecordMetaDataHook) BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) FDBRecord(com.apple.foundationdb.record.provider.foundationdb.FDBRecord) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) Subspace(com.apple.foundationdb.subspace.Subspace) IndexScanType(com.apple.foundationdb.record.IndexScanType) Pair(org.apache.commons.lang3.tuple.Pair) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) 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.allOf(org.hamcrest.Matchers.allOf) FDBDatabase(com.apple.foundationdb.record.provider.foundationdb.FDBDatabase) Arguments(org.junit.jupiter.params.provider.Arguments) Assertions.assertNotSame(org.junit.jupiter.api.Assertions.assertNotSame) TupleRange(com.apple.foundationdb.record.TupleRange) Stream(java.util.stream.Stream) PlanMatchers.indexName(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexName) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Expressions.function(com.apple.foundationdb.record.metadata.Key.Expressions.function) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) Assertions.fail(org.junit.jupiter.api.Assertions.fail) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) FunctionKeyExpression(com.apple.foundationdb.record.metadata.expressions.FunctionKeyExpression) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) MySimpleRecord(com.apple.foundationdb.record.TestRecords1Proto.MySimpleRecord) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) FDBTestBase(com.apple.foundationdb.record.provider.foundationdb.FDBTestBase) ArrayList(java.util.ArrayList) Lists(com.google.common.collect.Lists) 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) Tags(com.apple.test.Tags) ExecutionException(java.util.concurrent.ExecutionException) Assertions.assertArrayEquals(org.junit.jupiter.api.Assertions.assertArrayEquals) TestRecords2Proto(com.apple.foundationdb.record.TestRecords2Proto) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Matchers.hasItem(org.hamcrest.Matchers.hasItem) Index(com.apple.foundationdb.record.metadata.Index) Assumptions(org.junit.jupiter.api.Assumptions) TreeMap(java.util.TreeMap) AutoService(com.google.auto.service.AutoService) IndexEntry(com.apple.foundationdb.record.IndexEntry) Assertions.assertNotEquals(org.junit.jupiter.api.Assertions.assertNotEquals) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) FDBRecordVersion(com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion) 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) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) FDBRecordStoreBase(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase) MethodSource(org.junit.jupiter.params.provider.MethodSource) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) Matchers.lessThanOrEqualTo(org.hamcrest.Matchers.lessThanOrEqualTo) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) Collectors(java.util.stream.Collectors) Test(org.junit.jupiter.api.Test) PlanMatchers.hasTupleString(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasTupleString) KeyValueCursor(com.apple.foundationdb.record.provider.foundationdb.KeyValueCursor) List(java.util.List) ObjectPlanHash(com.apple.foundationdb.record.ObjectPlanHash) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) Optional(java.util.Optional) SortedMap(java.util.SortedMap) IntStream(java.util.stream.IntStream) PlanMatchers.indexScan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexScan) HashMap(java.util.HashMap) TestKeySpace(com.apple.foundationdb.record.provider.foundationdb.TestKeySpace) PlanHashable(com.apple.foundationdb.record.PlanHashable) Key(com.apple.foundationdb.record.metadata.Key) 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) Nonnull(javax.annotation.Nonnull) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) Versionstamp(com.apple.foundationdb.tuple.Versionstamp) Iterator(java.util.Iterator) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) RecordMetaDataHook(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreTestBase.RecordMetaDataHook) FDBDatabaseFactory(com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseFactory) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) RecordFunction(com.apple.foundationdb.record.RecordFunction) Collections(java.util.Collections) Message(com.google.protobuf.Message) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) IndexEntry(com.apple.foundationdb.record.IndexEntry) Index(com.apple.foundationdb.record.metadata.Index) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 24 with IndexEntry

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

the class VersionIndexTest method upgradeFormatVersions.

@ParameterizedTest(name = "upgradeFormatVersions [formatVersion = {0}, splitLongRecords = {1}]")
@MethodSource("formatVersionArguments")
@SuppressWarnings("try")
public void upgradeFormatVersions(int testFormatVersion, boolean splitLongRecords) {
    formatVersion = testFormatVersion;
    final RecordMetaDataHook hook = metaDataBuilder -> {
        simpleVersionHook.apply(metaDataBuilder);
        metaDataBuilder.setSplitLongRecords(splitLongRecords);
    };
    final List<Message> records = Arrays.asList(MySimpleRecord.newBuilder().setRecNo(1066L).setNumValue2(1).build(), MySimpleRecord.newBuilder().setRecNo(1415L).setNumValue2(1).build(), MySimpleRecord.newBuilder().setRecNo(1776L).setNumValue2(2).build());
    List<FDBStoredRecord<Message>> storedRecords;
    try (FDBRecordContext context = openContext(hook)) {
        List<FDBStoredRecord<Message>> storedRecordsWithIncompletes = records.stream().map(recordStore::saveRecord).collect(Collectors.toList());
        context.commit();
        byte[] globalVersion = context.getVersionStamp();
        storedRecords = storedRecordsWithIncompletes.stream().map(record -> record.withCommittedVersion(globalVersion)).collect(Collectors.toList());
    }
    try (FDBRecordContext context = openContext(hook)) {
        if (testFormatVersion < FDBRecordStore.SAVE_VERSION_WITH_RECORD_FORMAT_VERSION) {
            validateUsingOlderVersionFormat(storedRecords);
        } else {
            validateUsingNewerVersionFormat(storedRecords);
        }
    }
    // Update to the current format version
    formatVersion = FDBRecordStore.MAX_SUPPORTED_FORMAT_VERSION;
    if (testFormatVersion < FDBRecordStore.SAVE_VERSION_WITH_RECORD_FORMAT_VERSION && (splitLongRecords || testFormatVersion >= FDBRecordStore.SAVE_UNSPLIT_WITH_SUFFIX_FORMAT_VERSION)) {
        // After format version upgrade, each record should now store that it has the version inlined
        storedRecords = storedRecords.stream().map(record -> new FDBStoredRecord<>(record.getPrimaryKey(), record.getRecordType(), record.getRecord(), record.getKeyCount() + 1, record.getKeySize() * 2 + 1, record.getValueSize() + 1 + FDBRecordVersion.VERSION_LENGTH, record.isSplit(), true, record.getVersion())).collect(Collectors.toList());
    }
    try (FDBRecordContext context = openContext(hook)) {
        if (!splitLongRecords && testFormatVersion < FDBRecordStore.SAVE_UNSPLIT_WITH_SUFFIX_FORMAT_VERSION) {
            validateUsingOlderVersionFormat(storedRecords);
        } else {
            validateUsingNewerVersionFormat(storedRecords);
        }
        for (FDBStoredRecord<Message> storedRecord : storedRecords) {
            Optional<FDBRecordVersion> loadedVersion = recordStore.loadRecordVersion(storedRecord.getPrimaryKey());
            assertTrue(loadedVersion.isPresent());
            assertEquals(storedRecord.getVersion(), loadedVersion.get());
            RecordQuery query = RecordQuery.newBuilder().setFilter(Query.version().equalsValue(storedRecord.getVersion())).build();
            RecordQueryPlan plan = planner.plan(query);
            final String endpointString = "[" + storedRecord.getVersion().toVersionstamp(false).toString() + "]";
            assertThat(plan, indexScan(allOf(indexName("globalVersion"), bounds(hasTupleString("[" + endpointString + "," + endpointString + "]")))));
            List<FDBStoredRecord<Message>> queriedRecords = recordStore.executeQuery(plan).map(FDBQueriedRecord::getStoredRecord).asList().join();
            assertEquals(Collections.singletonList(storedRecord), queriedRecords);
        }
        assertTrue(recordStore.deleteRecord(storedRecords.get(0).getPrimaryKey()));
        final List<FDBStoredRecord<Message>> fewerRecords = storedRecords.subList(1, storedRecords.size());
        if (!splitLongRecords && testFormatVersion < FDBRecordStore.SAVE_UNSPLIT_WITH_SUFFIX_FORMAT_VERSION) {
            validateUsingOlderVersionFormat(fewerRecords);
        } else {
            validateUsingNewerVersionFormat(fewerRecords);
        }
        recordStore.saveRecord(storedRecords.get(0).getRecord());
        if (!splitLongRecords && testFormatVersion < FDBRecordStore.SAVE_UNSPLIT_WITH_SUFFIX_FORMAT_VERSION) {
            validateUsingOlderVersionFormat(fewerRecords);
        } else {
            validateUsingNewerVersionFormat(fewerRecords);
        }
    // do not commit (so we can do a second upgrade)
    }
    final Index newValueIndex = new Index("MySimpleRecord$num2", field("num_value_2"), IndexTypes.VALUE);
    final Index newVersionIndex = new Index("MySimpleRecord$version-num2", concat(VersionKeyExpression.VERSION, field("num_value_2")), IndexTypes.VERSION);
    final RecordMetaDataHook hookWithNewIndexes = metaDataBuilder -> {
        hook.apply(metaDataBuilder);
        metaDataBuilder.addIndex("MySimpleRecord", newValueIndex);
        metaDataBuilder.addIndex("MySimpleRecord", newVersionIndex);
    };
    final List<FDBStoredRecord<Message>> newStoredRecords;
    try (FDBRecordContext context = openContext(hookWithNewIndexes)) {
        assertTrue(recordStore.getRecordStoreState().isReadable(newValueIndex));
        boolean performedMigration = testFormatVersion < FDBRecordStore.SAVE_VERSION_WITH_RECORD_FORMAT_VERSION && (splitLongRecords || testFormatVersion >= FDBRecordStore.SAVE_UNSPLIT_WITH_SUFFIX_FORMAT_VERSION);
        assertNotEquals(performedMigration, recordStore.getRecordStoreState().isReadable(newVersionIndex));
        if (recordStore.getRecordStoreState().isReadable(newVersionIndex)) {
            // Validate versions are the same for all records in index and in primary store
            List<Pair<Tuple, FDBRecordVersion>> recordScannedValues = recordStore.scanRecords(null, ScanProperties.FORWARD_SCAN).map(record -> Pair.of(record.getPrimaryKey(), record.getVersion())).asList().join();
            List<Pair<Tuple, FDBRecordVersion>> indexedScannedValues = recordStore.scanIndex(newVersionIndex, IndexScanType.BY_VALUE, TupleRange.ALL, null, ScanProperties.FORWARD_SCAN).map(indexEntry -> Pair.of(TupleHelpers.subTuple(indexEntry.getKey(), 2, indexEntry.getKey().size()), FDBRecordVersion.fromVersionstamp(indexEntry.getKey().getVersionstamp(0), false))).asList().join();
            assertEquals(recordScannedValues, indexedScannedValues);
        }
        // Save record at newer version
        assertTrue(recordStore.deleteRecord(storedRecords.get(0).getPrimaryKey()));
        FDBStoredRecord<Message> newRecord0 = recordStore.saveRecord(storedRecords.get(0).getRecord());
        FDBStoredRecord<Message> newRecord2 = recordStore.saveRecord(storedRecords.get(2).getRecord());
        assertEquals(newRecord0.getVersion(), recordStore.loadRecordVersion(newRecord0.getPrimaryKey()).get());
        assertEquals(newRecord2.getVersion(), recordStore.loadRecordVersion(newRecord2.getPrimaryKey()).get());
        context.commit();
        byte[] versionstamp = context.getVersionStamp();
        newStoredRecords = Arrays.asList(newRecord0.withVersion(FDBRecordVersion.complete(versionstamp, 0)), storedRecords.get(1), newRecord2.withVersion(FDBRecordVersion.complete(versionstamp, 1)));
    }
    try (FDBRecordContext context = openContext(hookWithNewIndexes)) {
        if (!splitLongRecords && testFormatVersion < FDBRecordStore.SAVE_UNSPLIT_WITH_SUFFIX_FORMAT_VERSION) {
            validateUsingOlderVersionFormat(newStoredRecords);
        } else {
            validateUsingNewerVersionFormat(newStoredRecords);
        }
    }
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) FDBRecord(com.apple.foundationdb.record.provider.foundationdb.FDBRecord) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) Subspace(com.apple.foundationdb.subspace.Subspace) IndexScanType(com.apple.foundationdb.record.IndexScanType) Pair(org.apache.commons.lang3.tuple.Pair) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) 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.allOf(org.hamcrest.Matchers.allOf) FDBDatabase(com.apple.foundationdb.record.provider.foundationdb.FDBDatabase) Arguments(org.junit.jupiter.params.provider.Arguments) Assertions.assertNotSame(org.junit.jupiter.api.Assertions.assertNotSame) TupleRange(com.apple.foundationdb.record.TupleRange) Stream(java.util.stream.Stream) PlanMatchers.indexName(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexName) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Expressions.function(com.apple.foundationdb.record.metadata.Key.Expressions.function) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) Assertions.fail(org.junit.jupiter.api.Assertions.fail) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) FunctionKeyExpression(com.apple.foundationdb.record.metadata.expressions.FunctionKeyExpression) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) MySimpleRecord(com.apple.foundationdb.record.TestRecords1Proto.MySimpleRecord) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) FDBTestBase(com.apple.foundationdb.record.provider.foundationdb.FDBTestBase) ArrayList(java.util.ArrayList) Lists(com.google.common.collect.Lists) 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) Tags(com.apple.test.Tags) ExecutionException(java.util.concurrent.ExecutionException) Assertions.assertArrayEquals(org.junit.jupiter.api.Assertions.assertArrayEquals) TestRecords2Proto(com.apple.foundationdb.record.TestRecords2Proto) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Matchers.hasItem(org.hamcrest.Matchers.hasItem) Index(com.apple.foundationdb.record.metadata.Index) Assumptions(org.junit.jupiter.api.Assumptions) TreeMap(java.util.TreeMap) AutoService(com.google.auto.service.AutoService) IndexEntry(com.apple.foundationdb.record.IndexEntry) Assertions.assertNotEquals(org.junit.jupiter.api.Assertions.assertNotEquals) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) FDBRecordVersion(com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion) 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) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) FDBRecordStoreBase(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase) MethodSource(org.junit.jupiter.params.provider.MethodSource) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) Matchers.lessThanOrEqualTo(org.hamcrest.Matchers.lessThanOrEqualTo) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) Collectors(java.util.stream.Collectors) Test(org.junit.jupiter.api.Test) PlanMatchers.hasTupleString(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasTupleString) KeyValueCursor(com.apple.foundationdb.record.provider.foundationdb.KeyValueCursor) List(java.util.List) ObjectPlanHash(com.apple.foundationdb.record.ObjectPlanHash) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) Optional(java.util.Optional) SortedMap(java.util.SortedMap) IntStream(java.util.stream.IntStream) PlanMatchers.indexScan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexScan) HashMap(java.util.HashMap) TestKeySpace(com.apple.foundationdb.record.provider.foundationdb.TestKeySpace) PlanHashable(com.apple.foundationdb.record.PlanHashable) Key(com.apple.foundationdb.record.metadata.Key) 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) Nonnull(javax.annotation.Nonnull) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) Versionstamp(com.apple.foundationdb.tuple.Versionstamp) Iterator(java.util.Iterator) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) RecordMetaDataHook(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreTestBase.RecordMetaDataHook) FDBDatabaseFactory(com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseFactory) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) RecordFunction(com.apple.foundationdb.record.RecordFunction) Collections(java.util.Collections) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Message(com.google.protobuf.Message) Index(com.apple.foundationdb.record.metadata.Index) PlanMatchers.hasTupleString(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasTupleString) FDBRecordVersion(com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion) RecordMetaDataHook(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreTestBase.RecordMetaDataHook) FDBStoredRecord(com.apple.foundationdb.record.provider.foundationdb.FDBStoredRecord) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) Pair(org.apache.commons.lang3.tuple.Pair) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 25 with IndexEntry

use of com.apple.foundationdb.record.IndexEntry 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)

Aggregations

IndexEntry (com.apple.foundationdb.record.IndexEntry)74 Tuple (com.apple.foundationdb.tuple.Tuple)41 Nonnull (javax.annotation.Nonnull)37 Index (com.apple.foundationdb.record.metadata.Index)34 Test (org.junit.jupiter.api.Test)34 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)32 Message (com.google.protobuf.Message)32 ScanProperties (com.apple.foundationdb.record.ScanProperties)29 ArrayList (java.util.ArrayList)29 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)28 TupleRange (com.apple.foundationdb.record.TupleRange)28 List (java.util.List)28 Nullable (javax.annotation.Nullable)27 IndexScanType (com.apple.foundationdb.record.IndexScanType)24 RecordCursor (com.apple.foundationdb.record.RecordCursor)22 CompletableFuture (java.util.concurrent.CompletableFuture)21 Collectors (java.util.stream.Collectors)21 ExecuteProperties (com.apple.foundationdb.record.ExecuteProperties)20 TupleHelpers (com.apple.foundationdb.tuple.TupleHelpers)20 FDBStoreTimer (com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer)19