Search in sources :

Example 21 with ExecuteProperties

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

the class FDBOrQueryToUnionTest method testOrQuery5WithLimits.

@DualPlannerTest
@MethodSource("query5WithLimitsArgs")
@ParameterizedTest(name = "testOrQuery5WithLimits [limit = {0}, removesDuplicates = {1}]")
void testOrQuery5WithLimits(int limit, boolean removesDuplicates) throws Exception {
    RecordMetaDataHook hook = complexQuerySetupHook();
    complexQuerySetup(hook);
    setDeferFetchAfterUnionAndIntersection(true);
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.or(Query.field("str_value_indexed").lessThan("m"), Query.field("num_value_3_indexed").greaterThan(3))).setRemoveDuplicates(removesDuplicates).build();
    // Unordered(Index(MySimpleRecord$str_value_indexed ([null],[m])) ∪ Index(MySimpleRecord$num_value_3_indexed ([3],>))
    RecordQueryPlan plan = planner.plan(query);
    final BindingMatcher<RecordQueryUnorderedUnionPlan> unionPlanBindingMatcher = unorderedUnionPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$str_value_indexed")))), coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")))));
    final BindingMatcher<? extends RecordQueryPlan> planMatcher;
    if (removesDuplicates) {
        planMatcher = fetchFromPartialRecordPlan(unorderedPrimaryKeyDistinctPlan(unionPlanBindingMatcher));
    } else {
        planMatcher = fetchFromPartialRecordPlan(unionPlanBindingMatcher);
    }
    assertMatchesExactly(plan, planMatcher);
    if (planner instanceof RecordQueryPlanner) {
        assertEquals(removesDuplicates ? 1898767693 : 1898767686, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(removesDuplicates ? -583062018 : 212117636, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(removesDuplicates ? 1864525478 : -1635262164, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    } else {
        assertEquals(removesDuplicates ? 1898767693 : 1898767686, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
        assertEquals(removesDuplicates ? -583062018 : 212117636, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
        assertEquals(removesDuplicates ? 1864525478 : -1635262164, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    }
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context, hook);
        boolean done = false;
        byte[] continuation = null;
        Set<Tuple> uniqueKeys = new HashSet<>();
        int itr = 0;
        while (!done) {
            ExecuteProperties executeProperties = ExecuteProperties.newBuilder().setReturnedRowLimit(limit).build();
            try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan, continuation, executeProperties).asIterator()) {
                int i = 0;
                Set<Tuple> keysThisIteration = new HashSet<>();
                while (cursor.hasNext()) {
                    FDBQueriedRecord<Message> rec = cursor.next();
                    TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
                    myrec.mergeFrom(Objects.requireNonNull(rec).getRecord());
                    assertTrue(myrec.getStrValueIndexed().compareTo("m") < 0 || myrec.getNumValue3Indexed() > 3);
                    uniqueKeys.add(rec.getPrimaryKey());
                    if (removesDuplicates) {
                        assertThat(keysThisIteration.add(rec.getPrimaryKey()), is(true));
                    }
                    i++;
                }
                continuation = cursor.getContinuation();
                done = cursor.getNoNextReason().isSourceExhausted();
                if (!done) {
                    assertEquals(limit, i);
                }
            }
            itr++;
            assertThat("exceeded maximum iterations", itr, lessThan(500));
        }
        assertEquals(50 + 10, uniqueKeys.size());
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Message(com.google.protobuf.Message) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) 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) RecordQueryUnorderedUnionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryUnorderedUnionPlan) Tuple(com.apple.foundationdb.tuple.Tuple) HashSet(java.util.HashSet) MethodSource(org.junit.jupiter.params.provider.MethodSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 22 with ExecuteProperties

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

the class FDBRecordStoreQueryTest method queryWithShortTimeLimit.

/**
 * Verify that simple queries execute properly with short time limits.
 */
@DualPlannerTest
void queryWithShortTimeLimit() throws Exception {
    setupSimpleRecordStore(null, (i, builder) -> {
        builder.setRecNo(i);
        builder.setNumValue3Indexed(i / 10);
    });
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("num_value_3_indexed").equalsValue(5)).build();
    RecordQueryPlan plan = planner.plan(query);
    ExecuteProperties executeProperties = ExecuteProperties.newBuilder().setReturnedRowLimit(1000).setTimeLimit(1).setIsolationLevel(IsolationLevel.SERIALIZABLE).build();
    List<Long> list = new ArrayList<>();
    byte[] continuation = null;
    int count = 0;
    do {
        try (FDBRecordContext context = openContext()) {
            openSimpleRecordStore(context, null);
            long timeLeft = context.getTransactionCreateTime() + executeProperties.getTimeLimit() - System.currentTimeMillis();
            if (timeLeft > 0) {
                Thread.sleep(timeLeft);
            }
            count++;
            try (RecordCursor<Long> cursor = recordStore.executeQuery(plan, continuation, executeProperties).map(record -> TestRecords1Proto.MySimpleRecord.newBuilder().mergeFrom(record.getRecord()).getRecNo())) {
                cursor.forEach(list::add).join();
                RecordCursorResult<Long> result = cursor.getNext();
                continuation = result.getContinuation().toBytes();
                if (continuation == null) {
                    assertEquals(RecordCursor.NoNextReason.SOURCE_EXHAUSTED, result.getNoNextReason());
                } else {
                    assertEquals(RecordCursor.NoNextReason.TIME_LIMIT_REACHED, result.getNoNextReason());
                }
            }
        }
    } while (continuation != null);
    assertEquals(LongStream.range(50, 60).mapToObj(Long::valueOf).collect(Collectors.toList()), list);
    assertEquals(11, count);
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) ArrayList(java.util.ArrayList) RecordQuery(com.apple.foundationdb.record.query.RecordQuery)

Example 23 with ExecuteProperties

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

the class FDBSortQueryIndexSelectionTest method sortWithoutIndex.

@EnumSource(SortWithoutIndexMode.class)
@ParameterizedTest(name = "sortWithoutIndex [mode = {0}]")
public void sortWithoutIndex(SortWithoutIndexMode mode) throws Exception {
    final int numberOfRecordsToSave = 2000;
    final int numberOfResultsToReturn = 5;
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context);
        for (int i = 0; i < numberOfRecordsToSave; i++) {
            TestRecords1Proto.MySimpleRecord.Builder recBuilder = TestRecords1Proto.MySimpleRecord.newBuilder();
            // Slightly larger prime.
            recBuilder.setRecNo((2244 * i + 1649) % 2357);
            recBuilder.setNumValue2(i);
            recBuilder.setNumValue3Indexed(i % 5);
            recordStore.saveRecord(recBuilder.build());
        }
        commit(context);
    }
    RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("num_value_3_indexed").greaterThanOrEquals(2)).setSort(field("num_value_2"), true).build();
    if (mode == SortWithoutIndexMode.DISALLOWED) {
        assertThrows(RecordCoreException.class, () -> {
            planner.plan(query);
        });
        return;
    }
    ((RecordQueryPlanner) planner).setConfiguration(((RecordQueryPlanner) planner).getConfiguration().asBuilder().setAllowNonIndexSort(true).build());
    // Index(MySimpleRecord$num_value_3_indexed [[2],>) ORDER BY num_value_2 DESC
    RecordQueryPlan plan = planner.plan(query);
    assertThat(plan, sort(allOf(hasProperty("reverse", equalTo(true))), indexScan(allOf(indexName("MySimpleRecord$num_value_3_indexed"), bounds(hasTupleString("[[2],>"))))));
    assertEquals(256365917, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
    assertEquals(172993081, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
    assertEquals(748321565, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
    // Skip + limit is enough to overflow memory buffer. Skips into middle of section.
    final int skip = mode == SortWithoutIndexMode.FILE ? numberOfRecordsToSave / 2 + 1 : 0;
    ExecuteProperties.Builder executeProperties = ExecuteProperties.newBuilder().setSkip(skip).setReturnedRowLimit(numberOfResultsToReturn);
    final PrimitiveIterator.OfInt sortedInts = IntStream.iterate(numberOfRecordsToSave - 1, i -> i - 1).filter(i -> i % 5 >= 2).skip(skip).limit(numberOfResultsToReturn).iterator();
    try (FDBRecordContext context = openContext()) {
        openSimpleRecordStore(context);
        timer.reset();
        try (RecordCursor<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan, null, executeProperties.build())) {
            while (true) {
                RecordCursorResult<FDBQueriedRecord<Message>> next = cursor.getNext();
                if (!next.hasNext()) {
                    break;
                }
                FDBQueriedRecord<Message> rec = next.get();
                TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
                myrec.mergeFrom(rec.getRecord());
                assertTrue(sortedInts.hasNext());
                assertEquals(sortedInts.nextInt(), myrec.getNumValue2());
            }
        }
        assertFalse(sortedInts.hasNext());
        assertDiscardedNone(context);
        int countBeforeSorting = (numberOfRecordsToSave / 5) * 3;
        if (mode == SortWithoutIndexMode.MEMORY) {
            assertEquals(0, timer.getCount(SortEvents.Events.FILE_SORT_OPEN_FILE));
            assertEquals(countBeforeSorting, timer.getCount(SortEvents.Events.MEMORY_SORT_STORE_RECORD));
            assertEquals(numberOfResultsToReturn, timer.getCount(SortEvents.Events.MEMORY_SORT_LOAD_RECORD));
        } else {
            int nfiles = numberOfRecordsToSave / RecordQuerySortAdapter.DEFAULT_MAX_RECORD_COUNT_IN_MEMORY;
            assertEquals(nfiles, timer.getCount(SortEvents.Events.FILE_SORT_OPEN_FILE));
            assertEquals(nfiles - 1, timer.getCount(SortEvents.Events.FILE_SORT_MERGE_FILES));
            assertEquals(countBeforeSorting, timer.getCount(SortEvents.Events.FILE_SORT_SAVE_RECORD));
            assertEquals(numberOfResultsToReturn, timer.getCount(SortEvents.Events.FILE_SORT_LOAD_RECORD));
            assertEquals(skip / RecordQuerySortAdapter.DEFAULT_RECORD_COUNT_PER_SECTION, timer.getCount(SortEvents.Events.FILE_SORT_SKIP_SECTION));
            assertEquals(skip % RecordQuerySortAdapter.DEFAULT_RECORD_COUNT_PER_SECTION, timer.getCount(SortEvents.Events.FILE_SORT_SKIP_RECORD));
            assertThat(timer.getCount(SortEvents.Counts.FILE_SORT_FILE_BYTES), allOf(greaterThan(1000), lessThan(100000)));
        }
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Arrays(java.util.Arrays) Matchers.not(org.hamcrest.Matchers.not) 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) TestHelpers.assertDiscardedNone(com.apple.foundationdb.record.TestHelpers.assertDiscardedNone) RecordCursorResult(com.apple.foundationdb.record.RecordCursorResult) TestHelpers(com.apple.foundationdb.record.TestHelpers) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Expressions.concatenateFields(com.apple.foundationdb.record.metadata.Key.Expressions.concatenateFields) Expressions.concat(com.apple.foundationdb.record.metadata.Key.Expressions.concat) Tag(org.junit.jupiter.api.Tag) MethodSource(org.junit.jupiter.params.provider.MethodSource) PlanMatchers.coveringIndexScan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.coveringIndexScan) Query(com.apple.foundationdb.record.query.expressions.Query) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) IndexOptions(com.apple.foundationdb.record.metadata.IndexOptions) Matchers.allOf(org.hamcrest.Matchers.allOf) IndexMaintainerFactory(com.apple.foundationdb.record.provider.foundationdb.IndexMaintainerFactory) FanType(com.apple.foundationdb.record.metadata.expressions.KeyExpression.FanType) Arguments(org.junit.jupiter.params.provider.Arguments) Sets(com.google.common.collect.Sets) Test(org.junit.jupiter.api.Test) Objects(java.util.Objects) PlanMatchers.hasTupleString(com.apple.foundationdb.record.query.plan.match.PlanMatchers.hasTupleString) Stream(java.util.stream.Stream) PlanMatchers.indexName(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexName) Matchers.contains(org.hamcrest.Matchers.contains) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Matchers.equalTo(org.hamcrest.Matchers.equalTo) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) TestRecordsWithHeaderProto(com.apple.foundationdb.record.TestRecordsWithHeaderProto) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) PlanMatchers.typeFilter(com.apple.foundationdb.record.query.plan.match.PlanMatchers.typeFilter) IntStream(java.util.stream.IntStream) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) PlanMatchers.fetch(com.apple.foundationdb.record.query.plan.match.PlanMatchers.fetch) PlanMatchers.indexScan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.indexScan) EnumSource(org.junit.jupiter.params.provider.EnumSource) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) PlanHashable(com.apple.foundationdb.record.PlanHashable) PlanMatchers.filter(com.apple.foundationdb.record.query.plan.match.PlanMatchers.filter) Key(com.apple.foundationdb.record.metadata.Key) Matchers.hasProperty(org.hamcrest.Matchers.hasProperty) TestHelpers.assertDiscardedExactly(com.apple.foundationdb.record.TestHelpers.assertDiscardedExactly) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) RecordQuerySortAdapter(com.apple.foundationdb.record.query.plan.sorting.RecordQuerySortAdapter) PlanMatchers.scan(com.apple.foundationdb.record.query.plan.match.PlanMatchers.scan) RecordCursorIterator(com.apple.foundationdb.record.RecordCursorIterator) Matchers.lessThan(org.hamcrest.Matchers.lessThan) BooleanSource(com.apple.test.BooleanSource) ValueIndexMaintainerFactory(com.apple.foundationdb.record.provider.foundationdb.indexes.ValueIndexMaintainerFactory) 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) Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) Tags(com.apple.test.Tags) PlannableIndexTypes(com.apple.foundationdb.record.query.plan.PlannableIndexTypes) SortEvents(com.apple.foundationdb.record.sorting.SortEvents) PrimitiveIterator(java.util.PrimitiveIterator) AtomicLong(java.util.concurrent.atomic.AtomicLong) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Index(com.apple.foundationdb.record.metadata.Index) TestHelpers.assertDiscardedAtMost(com.apple.foundationdb.record.TestHelpers.assertDiscardedAtMost) PlanMatchers.unbounded(com.apple.foundationdb.record.query.plan.match.PlanMatchers.unbounded) AutoService(com.google.auto.service.AutoService) Matcher(org.hamcrest.Matcher) PlanMatchers.sort(com.apple.foundationdb.record.query.plan.match.PlanMatchers.sort) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) Collections(java.util.Collections) PrimitiveIterator(java.util.PrimitiveIterator) Message(com.google.protobuf.Message) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) 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) EnumSource(org.junit.jupiter.params.provider.EnumSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 24 with ExecuteProperties

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

the class FDBRecordStore method getRecordCountForRebuildIndexes.

/**
 * Get count of records to pass to a {@link UserVersionChecker} to decide whether to build right away. If all of the
 * new indexes are over a single type and that type has a record key prefix, then this count will only be over the
 * record type being indexed. If not, it will be the count of all records of all types, as in that case, the indexer
 * will need to scan the entire store to build each index. If determining the record count would be too costly (such
 * as if there is not an appropriate {@linkplain IndexTypes#COUNT count} index defined), this function may return
 * {@link Long#MAX_VALUE} to indicate that an unknown and unbounded number of records would have to be scanned
 * to build the index.
 *
 * @param newStore {@code true} if this is a brand new store
 * @param rebuildRecordCounts {@code true} if there is a record count key that needs to be rebuilt
 * @param indexes indexes that need to be built
 * @param singleRecordTypeWithPrefixKey either a single record type prefixed by the record type key or {@code null}
 * @return a future that completes to the record count for the version checker
 */
@Nonnull
@SuppressWarnings("PMD.EmptyCatchBlock")
protected CompletableFuture<Long> getRecordCountForRebuildIndexes(boolean newStore, boolean rebuildRecordCounts, @Nonnull Map<Index, List<RecordType>> indexes, @Nullable RecordType singleRecordTypeWithPrefixKey) {
    // Do this with the new indexes in write-only mode to avoid using one of them
    // when evaluating the snapshot record count.
    MutableRecordStoreState writeOnlyState = recordStoreStateRef.get().withWriteOnlyIndexes(indexes.keySet().stream().map(Index::getName).collect(Collectors.toList()));
    if (singleRecordTypeWithPrefixKey != null) {
        // Get a count for just those records, either from a COUNT index on just that type or from a universal COUNT index grouped by record type.
        MutableRecordStoreState saveState = recordStoreStateRef.get();
        try {
            recordStoreStateRef.set(writeOnlyState);
            return getSnapshotRecordCountForRecordType(singleRecordTypeWithPrefixKey.getName());
        } catch (RecordCoreException ex) {
        // No such index; have to use total record count.
        } finally {
            recordStoreStateRef.set(saveState);
        }
    }
    if (!rebuildRecordCounts) {
        MutableRecordStoreState saveState = recordStoreStateRef.get();
        try {
            recordStoreStateRef.set(writeOnlyState);
            // See: FDBRecordStoreBase.checkPossiblyRebuild() could take a long time if the record count index is split into many groups (https://github.com/FoundationDB/fdb-record-layer/issues/7)
            return getSnapshotRecordCount();
        } catch (RecordCoreException ex) {
        // Probably this was from the lack of appropriate index on count; treat like rebuildRecordCounts = true.
        } finally {
            recordStoreStateRef.set(saveState);
        }
    }
    // Do a scan (limited to a single record) to see if the store is empty.
    final ExecuteProperties executeProperties = ExecuteProperties.newBuilder().setReturnedRowLimit(1).setIsolationLevel(IsolationLevel.SNAPSHOT).build();
    final ScanProperties scanProperties = new ScanProperties(executeProperties);
    final RecordCursor<FDBStoredRecord<Message>> records;
    if (singleRecordTypeWithPrefixKey == null) {
        records = scanRecords(null, scanProperties);
    } else {
        records = scanRecords(TupleRange.allOf(singleRecordTypeWithPrefixKey.getRecordTypeKeyTuple()), null, scanProperties);
    }
    return records.onNext().thenApply(result -> {
        if (result.hasNext()) {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info(KeyValueLogMessage.of("version check scan found non-empty store", subspaceProvider.logKey(), subspaceProvider.toString(context)));
            }
            return Long.MAX_VALUE;
        } else {
            if (newStore ? LOGGER.isDebugEnabled() : LOGGER.isInfoEnabled()) {
                KeyValueLogMessage msg = KeyValueLogMessage.build("version check scan found empty store", subspaceProvider.logKey(), subspaceProvider.toString(context));
                if (newStore) {
                    LOGGER.debug(msg.toString());
                } else {
                    LOGGER.info(msg.toString());
                }
            }
            return 0L;
        }
    });
}
Also used : RecordCoreException(com.apple.foundationdb.record.RecordCoreException) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) MutableRecordStoreState(com.apple.foundationdb.record.MutableRecordStoreState) ScanProperties(com.apple.foundationdb.record.ScanProperties) FormerIndex(com.apple.foundationdb.record.metadata.FormerIndex) Index(com.apple.foundationdb.record.metadata.Index) KeyValueLogMessage(com.apple.foundationdb.record.logging.KeyValueLogMessage) Nonnull(javax.annotation.Nonnull) SpotBugsSuppressWarnings(com.apple.foundationdb.annotation.SpotBugsSuppressWarnings)

Example 25 with ExecuteProperties

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

the class FDBRecordStore method scanTypedRecords.

@Nonnull
public <M extends Message> RecordCursor<FDBStoredRecord<M>> scanTypedRecords(@Nonnull RecordSerializer<M> typedSerializer, @Nullable final Tuple low, @Nullable final Tuple high, @Nonnull final EndpointType lowEndpoint, @Nonnull final EndpointType highEndpoint, @Nullable byte[] continuation, @Nonnull ScanProperties scanProperties) {
    final RecordMetaData metaData = metaDataProvider.getRecordMetaData();
    final Subspace recordsSubspace = recordsSubspace();
    final SplitHelper.SizeInfo sizeInfo = new SplitHelper.SizeInfo();
    final RecordCursor<FDBRawRecord> rawRecords;
    if (metaData.isSplitLongRecords()) {
        RecordCursor<KeyValue> keyValues = KeyValueCursor.Builder.withSubspace(recordsSubspace).setContext(context).setContinuation(continuation).setLow(low, lowEndpoint).setHigh(high, highEndpoint).setScanProperties(scanProperties.with(ExecuteProperties::clearRowAndTimeLimits).with(ExecuteProperties::clearState)).build();
        rawRecords = new SplitHelper.KeyValueUnsplitter(context, recordsSubspace, keyValues, useOldVersionFormat(), sizeInfo, scanProperties.isReverse(), new CursorLimitManager(context, scanProperties.with(ExecuteProperties::clearReturnedRowLimit))).skip(scanProperties.getExecuteProperties().getSkip()).limitRowsTo(scanProperties.getExecuteProperties().getReturnedRowLimit());
    } else {
        KeyValueCursor.Builder keyValuesBuilder = KeyValueCursor.Builder.withSubspace(recordsSubspace).setContext(context).setContinuation(continuation).setLow(low, lowEndpoint).setHigh(high, highEndpoint);
        if (omitUnsplitRecordSuffix) {
            rawRecords = keyValuesBuilder.setScanProperties(scanProperties).build().map(kv -> {
                sizeInfo.set(kv);
                Tuple primaryKey = SplitHelper.unpackKey(recordsSubspace, kv);
                return new FDBRawRecord(primaryKey, kv.getValue(), null, sizeInfo);
            });
        } else {
            final ScanProperties finalScanProperties = scanProperties.with(executeProperties -> {
                final ExecuteProperties.Builder builder = executeProperties.toBuilder().clearTimeLimit().clearSkipAndAdjustLimit().clearState();
                int returnedRowLimit = builder.getReturnedRowLimitOrMax();
                if (returnedRowLimit != Integer.MAX_VALUE) {
                    // Adjust limit to twice the supplied limit in case there are versions in the records
                    builder.setReturnedRowLimit(2 * returnedRowLimit);
                }
                return builder.build();
            });
            rawRecords = new SplitHelper.KeyValueUnsplitter(context, recordsSubspace, keyValuesBuilder.setScanProperties(finalScanProperties).build(), useOldVersionFormat(), sizeInfo, scanProperties.isReverse(), new CursorLimitManager(context, scanProperties.with(ExecuteProperties::clearReturnedRowLimit))).skip(scanProperties.getExecuteProperties().getSkip()).limitRowsTo(scanProperties.getExecuteProperties().getReturnedRowLimit());
        }
    }
    RecordCursor<FDBStoredRecord<M>> result = rawRecords.mapPipelined(rawRecord -> {
        final Optional<CompletableFuture<FDBRecordVersion>> versionFutureOptional;
        if (useOldVersionFormat()) {
            // Older format versions: do a separate read to get the version.
            versionFutureOptional = loadRecordVersionAsync(rawRecord.getPrimaryKey(), scanProperties.getExecuteProperties().getIsolationLevel().isSnapshot());
        } else {
            // Newer format versions: the version is either in the record or it is not -- do not do another read.
            versionFutureOptional = Optional.empty();
        }
        return deserializeRecord(typedSerializer, rawRecord, metaData, versionFutureOptional);
    }, pipelineSizer.getPipelineSize(PipelineOperation.KEY_TO_RECORD));
    return context.instrument(FDBStoreTimer.Events.SCAN_RECORDS, result);
}
Also used : LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) UnaryOperator(java.util.function.UnaryOperator) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) RecordSerializer(com.apple.foundationdb.record.provider.common.RecordSerializer) Subspace(com.apple.foundationdb.subspace.Subspace) MutationType(com.apple.foundationdb.MutationType) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) Map(java.util.Map) RecordIndexUniquenessViolation(com.apple.foundationdb.record.RecordIndexUniquenessViolation) QueryToKeyMatcher(com.apple.foundationdb.record.query.QueryToKeyMatcher) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) Query(com.apple.foundationdb.record.query.expressions.Query) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) Set(java.util.Set) TupleRange(com.apple.foundationdb.record.TupleRange) KeySpacePath(com.apple.foundationdb.record.provider.foundationdb.keyspace.KeySpacePath) ByteOrder(java.nio.ByteOrder) SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) RecordMetaDataProvider(com.apple.foundationdb.record.RecordMetaDataProvider) RecordStoreState(com.apple.foundationdb.record.RecordStoreState) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) API(com.apple.foundationdb.annotation.API) FunctionNames(com.apple.foundationdb.record.FunctionNames) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) RangeSet(com.apple.foundationdb.async.RangeSet) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Supplier(java.util.function.Supplier) FormerIndex(com.apple.foundationdb.record.metadata.FormerIndex) ArrayList(java.util.ArrayList) ByteScanLimiter(com.apple.foundationdb.record.ByteScanLimiter) ParameterRelationshipGraph(com.apple.foundationdb.record.query.ParameterRelationshipGraph) LoggableException(com.apple.foundationdb.util.LoggableException) CloseableAsyncIterator(com.apple.foundationdb.async.CloseableAsyncIterator) IndexRecordFunction(com.apple.foundationdb.record.metadata.IndexRecordFunction) Nullable(javax.annotation.Nullable) ByteArrayUtil2(com.apple.foundationdb.tuple.ByteArrayUtil2) IsolationLevel(com.apple.foundationdb.record.IsolationLevel) CursorLimitManager(com.apple.foundationdb.record.cursors.CursorLimitManager) ExecuteState(com.apple.foundationdb.record.ExecuteState) AtomicLong(java.util.concurrent.atomic.AtomicLong) RecordType(com.apple.foundationdb.record.metadata.RecordType) Index(com.apple.foundationdb.record.metadata.Index) DynamicMessageRecordSerializer(com.apple.foundationdb.record.provider.common.DynamicMessageRecordSerializer) SyntheticRecordPlanner(com.apple.foundationdb.record.query.plan.synthetic.SyntheticRecordPlanner) IndexEntry(com.apple.foundationdb.record.IndexEntry) LoggerFactory(org.slf4j.LoggerFactory) RecordCoreStorageException(com.apple.foundationdb.record.RecordCoreStorageException) ByteBuffer(java.nio.ByteBuffer) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) Transaction(com.apple.foundationdb.Transaction) Tuple(com.apple.foundationdb.tuple.Tuple) Range(com.apple.foundationdb.Range) KeyValueLogMessage(com.apple.foundationdb.record.logging.KeyValueLogMessage) PipelineOperation(com.apple.foundationdb.record.PipelineOperation) RecordMetaDataProto(com.apple.foundationdb.record.RecordMetaDataProto) ByteArrayUtil(com.apple.foundationdb.tuple.ByteArrayUtil) KeyValue(com.apple.foundationdb.KeyValue) ImmutableMap(com.google.common.collect.ImmutableMap) Predicate(java.util.function.Predicate) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) IndexQueryabilityFilter(com.apple.foundationdb.record.query.IndexQueryabilityFilter) AndComponent(com.apple.foundationdb.record.query.expressions.AndComponent) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) Collectors(java.util.stream.Collectors) ByteString(com.google.protobuf.ByteString) List(java.util.List) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) AggregateFunctionNotSupportedException(com.apple.foundationdb.record.AggregateFunctionNotSupportedException) RecordTypeKeyComparison(com.apple.foundationdb.record.query.expressions.RecordTypeKeyComparison) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) Optional(java.util.Optional) MutableRecordStoreState(com.apple.foundationdb.record.MutableRecordStoreState) RecordTypeOrBuilder(com.apple.foundationdb.record.metadata.RecordTypeOrBuilder) SyntheticRecordFromStoredRecordPlan(com.apple.foundationdb.record.query.plan.synthetic.SyntheticRecordFromStoredRecordPlan) SpotBugsSuppressWarnings(com.apple.foundationdb.annotation.SpotBugsSuppressWarnings) Descriptors(com.google.protobuf.Descriptors) AsyncIterator(com.apple.foundationdb.async.AsyncIterator) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) CursorStreamingMode(com.apple.foundationdb.record.CursorStreamingMode) Key(com.apple.foundationdb.record.metadata.Key) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) EndpointType(com.apple.foundationdb.record.EndpointType) ScanProperties(com.apple.foundationdb.record.ScanProperties) Suppliers(com.google.common.base.Suppliers) LinkedList(java.util.LinkedList) Nonnull(javax.annotation.Nonnull) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) MoreAsyncUtil(com.apple.foundationdb.async.MoreAsyncUtil) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) IndexState(com.apple.foundationdb.record.IndexState) StoreRecordFunction(com.apple.foundationdb.record.metadata.StoreRecordFunction) ReadTransaction(com.apple.foundationdb.ReadTransaction) AsyncIterable(com.apple.foundationdb.async.AsyncIterable) FDBRecordStoreStateCache(com.apple.foundationdb.record.provider.foundationdb.storestate.FDBRecordStoreStateCache) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) KeyValue(com.apple.foundationdb.KeyValue) CursorLimitManager(com.apple.foundationdb.record.cursors.CursorLimitManager) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) CompletableFuture(java.util.concurrent.CompletableFuture) ScanProperties(com.apple.foundationdb.record.ScanProperties) Subspace(com.apple.foundationdb.subspace.Subspace) Tuple(com.apple.foundationdb.tuple.Tuple) Nonnull(javax.annotation.Nonnull)

Aggregations

ExecuteProperties (com.apple.foundationdb.record.ExecuteProperties)38 Nonnull (javax.annotation.Nonnull)29 Message (com.google.protobuf.Message)23 RecordCursor (com.apple.foundationdb.record.RecordCursor)20 ScanProperties (com.apple.foundationdb.record.ScanProperties)18 List (java.util.List)17 Index (com.apple.foundationdb.record.metadata.Index)15 FDBQueriedRecord (com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord)15 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)15 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)15 RecordCursorResult (com.apple.foundationdb.record.RecordCursorResult)14 Function (java.util.function.Function)14 Nullable (javax.annotation.Nullable)13 API (com.apple.foundationdb.annotation.API)12 EvaluationContext (com.apple.foundationdb.record.EvaluationContext)12 Tuple (com.apple.foundationdb.tuple.Tuple)12 IsolationLevel (com.apple.foundationdb.record.IsolationLevel)11 TupleRange (com.apple.foundationdb.record.TupleRange)11 ArrayList (java.util.ArrayList)11 Collections (java.util.Collections)10