Search in sources :

Example 21 with RecordCursor

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

the class SortCursorTests method memorySortContinuations.

@Test
public void memorySortContinuations() throws Exception {
    final Function<byte[], RecordCursor<FDBQueriedRecord<Message>>> scanRecords = continuation -> {
        final ExecuteProperties executeProperties = ExecuteProperties.newBuilder().setScannedRecordsLimit(20).build();
        return recordStore.scanRecords(null, null, EndpointType.TREE_START, EndpointType.TREE_END, continuation, new ScanProperties(executeProperties)).map(FDBQueriedRecord::stored);
    };
    final MemoryAdapterBase adapter = new MemoryAdapterBase() {

        @Override
        public int getMaxRecordCountInMemory() {
            return 10;
        }
    };
    List<Integer> resultNums = new ArrayList<>();
    byte[] continuation = null;
    int transactionCount = 0;
    do {
        try (FDBRecordContext context = openContext()) {
            openSimpleRecordStore(context);
            try (RecordCursor<FDBQueriedRecord<Message>> cursor = MemorySortCursor.create(adapter, scanRecords, timer, continuation)) {
                while (true) {
                    RecordCursorResult<FDBQueriedRecord<Message>> result = cursor.getNext();
                    if (result.hasNext()) {
                        int num2 = TestRecords1Proto.MySimpleRecord.newBuilder().mergeFrom(result.get().getRecord()).getNumValue2();
                        resultNums.add(num2);
                    } else {
                        continuation = result.getContinuation().toBytes();
                        break;
                    }
                }
            }
            transactionCount++;
        }
    } while (continuation != null);
    assertEquals(110, transactionCount);
    assertEquals(sortedNums, resultNums);
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) FileSortAdapter(com.apple.foundationdb.record.sorting.FileSortAdapter) MemorySortAdapter(com.apple.foundationdb.record.sorting.MemorySortAdapter) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Random(java.util.Random) Function(java.util.function.Function) KeyGenerator(javax.crypto.KeyGenerator) ArrayList(java.util.ArrayList) Key(com.apple.foundationdb.record.metadata.Key) SecureRandom(java.security.SecureRandom) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) FileSortCursor(com.apple.foundationdb.record.sorting.FileSortCursor) Tuple(com.apple.foundationdb.tuple.Tuple) RecordCursorResult(com.apple.foundationdb.record.RecordCursorResult) EndpointType(com.apple.foundationdb.record.EndpointType) ScanProperties(com.apple.foundationdb.record.ScanProperties) SortedRecordSerializer(com.apple.foundationdb.record.provider.foundationdb.SortedRecordSerializer) Tag(org.junit.jupiter.api.Tag) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Nonnull(javax.annotation.Nonnull) CodedOutputStream(com.google.protobuf.CodedOutputStream) Nullable(javax.annotation.Nullable) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) MemorySortCursor(com.apple.foundationdb.record.sorting.MemorySortCursor) Tags(com.apple.test.Tags) IOException(java.io.IOException) CipherPool(com.apple.foundationdb.record.provider.common.CipherPool) File(java.io.File) FDBRecordStoreTestBase(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreTestBase) Test(org.junit.jupiter.api.Test) List(java.util.List) CodedInputStream(com.google.protobuf.CodedInputStream) MemorySorter(com.apple.foundationdb.record.sorting.MemorySorter) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) SecretKey(javax.crypto.SecretKey) DynamicMessageRecordSerializer(com.apple.foundationdb.record.provider.common.DynamicMessageRecordSerializer) Collections(java.util.Collections) RecordCursor(com.apple.foundationdb.record.RecordCursor) Message(com.google.protobuf.Message) ArrayList(java.util.ArrayList) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) ScanProperties(com.apple.foundationdb.record.ScanProperties) Test(org.junit.jupiter.api.Test)

Example 22 with RecordCursor

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

the class SortCursorTests method memorySort.

@Test
public void memorySort() throws Exception {
    final Function<byte[], RecordCursor<FDBQueriedRecord<Message>>> scanRecords = continuation -> recordStore.scanRecords(null, null, EndpointType.TREE_START, EndpointType.TREE_END, continuation, ScanProperties.FORWARD_SCAN).map(FDBQueriedRecord::stored);
    final MemoryAdapterBase adapter = new MemoryAdapterBase() {

        @Override
        public int getMaxRecordCountInMemory() {
            return 20;
        }
    };
    List<Integer> resultNums;
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context);
        try (RecordCursor<FDBQueriedRecord<Message>> cursor = MemorySortCursor.create(adapter, scanRecords, timer, null)) {
            resultNums = cursor.map(r -> TestRecords1Proto.MySimpleRecord.newBuilder().mergeFrom(r.getRecord()).getNumValue2()).asList().get();
        }
    }
    assertEquals(sortedNums.subList(0, 20), resultNums);
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) FileSortAdapter(com.apple.foundationdb.record.sorting.FileSortAdapter) MemorySortAdapter(com.apple.foundationdb.record.sorting.MemorySortAdapter) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Random(java.util.Random) Function(java.util.function.Function) KeyGenerator(javax.crypto.KeyGenerator) ArrayList(java.util.ArrayList) Key(com.apple.foundationdb.record.metadata.Key) SecureRandom(java.security.SecureRandom) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) FileSortCursor(com.apple.foundationdb.record.sorting.FileSortCursor) Tuple(com.apple.foundationdb.tuple.Tuple) RecordCursorResult(com.apple.foundationdb.record.RecordCursorResult) EndpointType(com.apple.foundationdb.record.EndpointType) ScanProperties(com.apple.foundationdb.record.ScanProperties) SortedRecordSerializer(com.apple.foundationdb.record.provider.foundationdb.SortedRecordSerializer) Tag(org.junit.jupiter.api.Tag) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Nonnull(javax.annotation.Nonnull) CodedOutputStream(com.google.protobuf.CodedOutputStream) Nullable(javax.annotation.Nullable) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) MemorySortCursor(com.apple.foundationdb.record.sorting.MemorySortCursor) Tags(com.apple.test.Tags) IOException(java.io.IOException) CipherPool(com.apple.foundationdb.record.provider.common.CipherPool) File(java.io.File) FDBRecordStoreTestBase(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreTestBase) Test(org.junit.jupiter.api.Test) List(java.util.List) CodedInputStream(com.google.protobuf.CodedInputStream) MemorySorter(com.apple.foundationdb.record.sorting.MemorySorter) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) SecretKey(javax.crypto.SecretKey) DynamicMessageRecordSerializer(com.apple.foundationdb.record.provider.common.DynamicMessageRecordSerializer) Collections(java.util.Collections) RecordCursor(com.apple.foundationdb.record.RecordCursor) Message(com.google.protobuf.Message) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Test(org.junit.jupiter.api.Test)

Example 23 with RecordCursor

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

the class FDBRecordStoreQueryTestBase method querySimpleRecordStoreWithContinuation.

/**
 * A query execution utility that can handle continuations. This is very similar to the above {@link #querySimpleRecordStore}
 * with the additional support for {@link ExecuteProperties} and continuation.
 * This method returns the last result encountered. In the case where the row limit was encountered, this would be the one
 * result that contains the continuation that should be used on the next call.
 * @param recordMetaDataHook Metadata hook to invoke while opening store
 * @param plan the plan to execute
 * @param contextSupplier provider method to get execution context
 * @param continuation execution continuation
 * @param executeProperties execution properties to pass into the execute method
 * @param checkNumRecords Consumer that verifies correct number of records returned
 * @param checkRecord Consumer that asserts every record retrieved
 * @param checkDiscarded Consumer that asserts the number of discarded records
 * @return the last result from the cursor
 * @throws Throwable any thrown exception, or its cause if the exception is a {@link ExecutionException}
 */
protected RecordCursorResult<FDBQueriedRecord<Message>> querySimpleRecordStoreWithContinuation(@Nonnull RecordMetaDataHook recordMetaDataHook, @Nonnull RecordQueryPlan plan, @Nonnull Supplier<EvaluationContext> contextSupplier, @Nullable byte[] continuation, @Nonnull ExecuteProperties executeProperties, @Nonnull Consumer<Integer> checkNumRecords, @Nonnull Consumer<TestRecords1Proto.MySimpleRecord.Builder> checkRecord, @Nonnull Consumer<FDBRecordContext> checkDiscarded) throws Throwable {
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context, recordMetaDataHook);
        AtomicInteger i = new AtomicInteger(0);
        CompletableFuture<RecordCursorResult<FDBQueriedRecord<Message>>> lastResult;
        RecordCursor<FDBQueriedRecord<Message>> cursor = plan.execute(recordStore, contextSupplier.get(), continuation, executeProperties);
        lastResult = cursor.forEachResult(result -> {
            TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
            myrec.mergeFrom(result.get().getRecord());
            checkRecord.accept(myrec);
            i.incrementAndGet();
        });
        lastResult.get();
        checkNumRecords.accept(i.get());
        checkDiscarded.accept(context);
        // TODO a hack until this gets refactored properly
        clearStoreCounter(context);
        return lastResult.get();
    } catch (ExecutionException ex) {
        throw ex.getCause();
    }
}
Also used : IntStream(java.util.stream.IntStream) Assertions.fail(org.junit.jupiter.api.Assertions.fail) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) TestRecords3Proto(com.apple.foundationdb.record.TestRecords3Proto) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) CompletableFuture(java.util.concurrent.CompletableFuture) TestRecordsTupleFieldsProto(com.apple.foundationdb.record.TestRecordsTupleFieldsProto) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) RecordCursorResult(com.apple.foundationdb.record.RecordCursorResult) TestHelpers(com.apple.foundationdb.record.TestHelpers) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Expressions.concatenateFields(com.apple.foundationdb.record.metadata.Key.Expressions.concatenateFields) RecordCursorIterator(com.apple.foundationdb.record.RecordCursorIterator) BiConsumer(java.util.function.BiConsumer) Expressions.concat(com.apple.foundationdb.record.metadata.Key.Expressions.concat) Nonnull(javax.annotation.Nonnull) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) Nullable(javax.annotation.Nullable) TestRecords4Proto(com.apple.foundationdb.record.TestRecords4Proto) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) TupleFieldsHelper(com.apple.foundationdb.record.metadata.expressions.TupleFieldsHelper) FanType(com.apple.foundationdb.record.metadata.expressions.KeyExpression.FanType) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) FDBRecordStoreTestBase(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreTestBase) ExecutionException(java.util.concurrent.ExecutionException) Consumer(java.util.function.Consumer) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) List(java.util.List) BindingMatcher(com.apple.foundationdb.record.query.plan.temp.matchers.BindingMatcher) TestRecords5Proto(com.apple.foundationdb.record.TestRecords5Proto) Index(com.apple.foundationdb.record.metadata.Index) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) TestRecordsEnumProto(com.apple.foundationdb.record.TestRecordsEnumProto) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) TestRecordsWithHeaderProto(com.apple.foundationdb.record.TestRecordsWithHeaderProto) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) Message(com.google.protobuf.Message) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) RecordCursorResult(com.apple.foundationdb.record.RecordCursorResult) ExecutionException(java.util.concurrent.ExecutionException)

Example 24 with RecordCursor

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

the class FDBRestrictedIndexQueryTest method queryAllowedIndexes.

/**
 * Verify that queries do not use prohibited indexes.
 */
@DualPlannerTest
void queryAllowedIndexes() {
    RecordMetaDataHook hook = metaData -> {
        metaData.removeIndex("MySimpleRecord$str_value_indexed");
        metaData.addIndex("MySimpleRecord", new Index("limited_str_value_index", field("str_value_indexed"), Index.EMPTY_VALUE, IndexTypes.VALUE, IndexOptions.NOT_ALLOWED_FOR_QUERY_OPTIONS));
    };
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context, hook);
        recordStore.deleteAllRecords();
        TestRecords1Proto.MySimpleRecord.Builder recBuilder = TestRecords1Proto.MySimpleRecord.newBuilder();
        recBuilder.setRecNo(1);
        recBuilder.setStrValueIndexed("abc");
        recBuilder.setNumValueUnique(123);
        recordStore.saveRecord(recBuilder.build());
        recBuilder.setRecNo(2);
        recBuilder.setStrValueIndexed("xyz");
        recBuilder.setNumValueUnique(987);
        recordStore.saveRecord(recBuilder.build());
        commit(context);
    }
    RecordQuery query1 = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("str_value_indexed").equalsValue("abc")).build();
    // Index(limited_str_value_index [[abc],[abc]])
    // Scan(<,>) | [MySimpleRecord] | str_value_indexed EQUALS abc
    RecordQueryPlan plan1 = planner.plan(query1);
    assertThat("should not use prohibited index", plan1, hasNoDescendant(indexScan("limited_str_value_index")));
    assertTrue(plan1.hasFullRecordScan(), "should use full record scan");
    if (planner instanceof RecordQueryPlanner) {
        assertEquals(-223683738, plan1.planHash(PlanHashable.PlanHashKind.LEGACY));
    // TODO: Issue https://github.com/FoundationDB/fdb-record-layer/issues/1074
    // assertEquals(1148834070, plan1.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        assertEquals(-2136471589, plan1.planHash(PlanHashable.PlanHashKind.LEGACY));
    }
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context, hook);
        try (RecordCursor<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan1)) {
            FDBQueriedRecord<Message> rec = cursor.getNext().get();
            TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
            myrec.mergeFrom(Objects.requireNonNull(rec).getRecord());
            assertEquals("abc", myrec.getStrValueIndexed());
            assertFalse(cursor.getNext().hasNext());
        }
        TestHelpers.assertDiscardedExactly(1, context);
        clearStoreCounter(context);
    }
    RecordQuery query2 = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("str_value_indexed").equalsValue("abc")).setAllowedIndex("limited_str_value_index").build();
    // Index(limited_str_value_index [[abc],[abc]])
    RecordQueryPlan plan2 = planner.plan(query2);
    assertThat("explicitly use prohibited index", plan2, descendant(indexScan("limited_str_value_index")));
    assertFalse(plan2.hasRecordScan(), "should not use record scan");
    assertEquals(-1573180774, plan2.planHash(PlanHashable.PlanHashKind.LEGACY));
    assertEquals(994464666, plan2.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
    assertEquals(-1531627068, plan2.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context, hook);
        try (RecordCursor<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan2)) {
            FDBQueriedRecord<Message> rec = cursor.getNext().get();
            TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
            myrec.mergeFrom(Objects.requireNonNull(rec).getRecord());
            assertEquals("abc", myrec.getStrValueIndexed());
            assertFalse(cursor.getNext().hasNext());
        }
        TestHelpers.assertDiscardedNone(context);
    }
}
Also used : LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) 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) TestHelpers(com.apple.foundationdb.record.TestHelpers) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) Tag(org.junit.jupiter.api.Tag) Query(com.apple.foundationdb.record.query.expressions.Query) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) IndexOptions(com.apple.foundationdb.record.metadata.IndexOptions) Predicate(java.util.function.Predicate) Matchers.allOf(org.hamcrest.Matchers.allOf) IndexQueryabilityFilter(com.apple.foundationdb.record.query.IndexQueryabilityFilter) TupleRange(com.apple.foundationdb.record.TupleRange) Test(org.junit.jupiter.api.Test) Objects(java.util.Objects) PlanMatchers.hasTupleString(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasTupleString) List(java.util.List) PlanMatchers.indexName(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexName) RecordStoreState(com.apple.foundationdb.record.RecordStoreState) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) PlanMatchers.hasNoDescendant(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasNoDescendant) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) AggregateFunctionNotSupportedException(com.apple.foundationdb.record.AggregateFunctionNotSupportedException) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) Matchers.containsString(org.hamcrest.Matchers.containsString) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) FunctionNames(com.apple.foundationdb.record.FunctionNames) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) PlanMatchers.indexScan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexScan) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) CompletableFuture(java.util.concurrent.CompletableFuture) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) RangeSet(com.apple.foundationdb.async.RangeSet) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Function(java.util.function.Function) PlanHashable(com.apple.foundationdb.record.PlanHashable) Key(com.apple.foundationdb.record.metadata.Key) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Nonnull(javax.annotation.Nonnull) Expressions.field(com.apple.foundationdb.record.metadata.Key.Expressions.field) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) IsolationLevel(com.apple.foundationdb.record.IsolationLevel) Tags(com.apple.test.Tags) Index(com.apple.foundationdb.record.metadata.Index) Executable(org.junit.jupiter.api.function.Executable) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) PlanMatchers.descendant(com.apple.foundationdb.record.query.plan.match.PlanMatchers.descendant) 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) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) RecordQuery(com.apple.foundationdb.record.query.RecordQuery)

Example 25 with RecordCursor

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

the class KeySpaceDirectoryTest method testListObeysTimeLimits.

@Test
public void testListObeysTimeLimits() {
    KeySpace root = new KeySpace(new KeySpaceDirectory("root", KeyType.STRING, "root-" + random.nextInt(Integer.MAX_VALUE)).addSubdirectory(new KeySpaceDirectory("a", KeyType.LONG).addSubdirectory(new KeySpaceDirectory("b", KeyType.LONG).addSubdirectory(new KeySpaceDirectory("c", KeyType.LONG)))));
    final FDBDatabase database = FDBDatabaseFactory.instance().getDatabase();
    try (FDBRecordContext context = database.openContext()) {
        Transaction tr = context.ensureActive();
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 3; j++) {
                for (int k = 0; k < 5; k++) {
                    tr.set(root.path("root").add("a", i).add("b", j).add("c", k).toTuple(context).pack(), Tuple.from(i + j).pack());
                }
            }
        }
        tr.commit().join();
    }
    try (FDBRecordContext context = database.openContext()) {
        // Iteration will inject a 1ms pause in each "a" value we iterate over (there are 10 of them)
        // so we want to make the time limit long enough to make *some* progress, but short enough to
        // to make sure we cannot get them all.
        ScanProperties props = new ScanProperties(ExecuteProperties.newBuilder().setFailOnScanLimitReached(false).setTimeLimit(5L).build());
        // The inner and outer iterator are declared here instead of in-line with the call to flatMapPipelined
        // because IntelliJ was having issues groking the call as a single call.
        Function<byte[], RecordCursor<ResolvedKeySpacePath>> aIterator = outerContinuation -> root.path("root").listSubdirectoryAsync(context, "a", outerContinuation, props).map(value -> {
            sleep(1L);
            return value;
        });
        BiFunction<ResolvedKeySpacePath, byte[], RecordCursor<ResolvedKeySpacePath>> bIterator = (aPath, innerContinuation) -> aPath.toPath().add("b", 0).listSubdirectoryAsync(context, "c", innerContinuation, props);
        RecordCursor<ResolvedKeySpacePath> cursor = RecordCursor.flatMapPipelined(aIterator, bIterator, null, 10);
        long count = cursor.getCount().join();
        assertEquals(RecordCursor.NoNextReason.TIME_LIMIT_REACHED, cursor.getNext().getNoNextReason());
        // With a 1ms delay we should read no more than 5 "a" values (there are a total of 10)
        // and each "c" value has 4 values. so we shouldn't have been able to read more than 40
        // total values.
        assertTrue(count <= 40, "Read too many values, query should have timed out");
    }
}
Also used : Arrays(java.util.Arrays) IsInstanceOf.instanceOf(org.hamcrest.core.IsInstanceOf.instanceOf) BiFunction(java.util.function.BiFunction) Assertions.assertNotEquals(org.junit.jupiter.api.Assertions.assertNotEquals) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Random(java.util.Random) Transaction(com.apple.foundationdb.Transaction) Tuple(com.apple.foundationdb.tuple.Tuple) KeyValueLogMessage(com.apple.foundationdb.record.logging.KeyValueLogMessage) Pair(org.apache.commons.lang3.tuple.Pair) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) Map(java.util.Map) Matchers.nullValue(org.hamcrest.Matchers.nullValue) Tag(org.junit.jupiter.api.Tag) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) FDBDatabase(com.apple.foundationdb.record.provider.foundationdb.FDBDatabase) UUID(java.util.UUID) Assertions.assertNotSame(org.junit.jupiter.api.Assertions.assertNotSame) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) Collectors(java.util.stream.Collectors) Matchers.startsWith(org.hamcrest.Matchers.startsWith) Test(org.junit.jupiter.api.Test) List(java.util.List) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) RandomStringUtils(org.apache.commons.lang3.RandomStringUtils) Matchers.is(org.hamcrest.Matchers.is) DEFAULT_CHECK(com.apple.foundationdb.record.provider.foundationdb.keyspace.ResolverCreateHooks.DEFAULT_CHECK) IntStream(java.util.stream.IntStream) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) Function(java.util.function.Function) Supplier(java.util.function.Supplier) FDBTestBase(com.apple.foundationdb.record.provider.foundationdb.FDBTestBase) ArrayList(java.util.ArrayList) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) KeyType(com.apple.foundationdb.record.provider.foundationdb.keyspace.KeySpaceDirectory.KeyType) TestHelpers.eventually(com.apple.foundationdb.record.TestHelpers.eventually) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) EndpointType(com.apple.foundationdb.record.EndpointType) ScanProperties(com.apple.foundationdb.record.ScanProperties) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) LinkedList(java.util.LinkedList) NoSuchElementException(java.util.NoSuchElementException) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) Iterator(java.util.Iterator) Tags(com.apple.test.Tags) ScopedInterningLayer(com.apple.foundationdb.record.provider.foundationdb.layers.interning.ScopedInterningLayer) TimeUnit(java.util.concurrent.TimeUnit) Assertions.assertArrayEquals(org.junit.jupiter.api.Assertions.assertArrayEquals) TestHelpers.assertThrows(com.apple.foundationdb.record.TestHelpers.assertThrows) FDBDatabaseFactory(com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseFactory) RecordCursor(com.apple.foundationdb.record.RecordCursor) ValueRange(com.apple.foundationdb.record.ValueRange) RecordCursor(com.apple.foundationdb.record.RecordCursor) FDBDatabase(com.apple.foundationdb.record.provider.foundationdb.FDBDatabase) Transaction(com.apple.foundationdb.Transaction) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) ScanProperties(com.apple.foundationdb.record.ScanProperties) Test(org.junit.jupiter.api.Test)

Aggregations

RecordCursor (com.apple.foundationdb.record.RecordCursor)66 List (java.util.List)59 Nonnull (javax.annotation.Nonnull)57 Message (com.google.protobuf.Message)50 Collections (java.util.Collections)48 Function (java.util.function.Function)48 ArrayList (java.util.ArrayList)47 ExecuteProperties (com.apple.foundationdb.record.ExecuteProperties)46 Tuple (com.apple.foundationdb.tuple.Tuple)44 Test (org.junit.jupiter.api.Test)43 ScanProperties (com.apple.foundationdb.record.ScanProperties)42 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)40 RecordCursorResult (com.apple.foundationdb.record.RecordCursorResult)39 Tags (com.apple.test.Tags)37 Collectors (java.util.stream.Collectors)37 Tag (org.junit.jupiter.api.Tag)37 Arrays (java.util.Arrays)36 Nullable (javax.annotation.Nullable)35 Index (com.apple.foundationdb.record.metadata.Index)34 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)33