Search in sources :

Example 66 with IndexEntry

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

the class ComposedBitmapIndexCursor method computeNextResultStates.

@Nonnull
@Override
protected CompletableFuture<List<MergeCursorState<IndexEntry>>> computeNextResultStates() {
    final List<MergeCursorState<IndexEntry>> cursorStates = getCursorStates();
    return whenAll(cursorStates).thenApply(vignore -> {
        boolean anyHasNext = false;
        for (MergeCursorState<IndexEntry> cursorState : cursorStates) {
            if (cursorState.getResult().hasNext()) {
                anyHasNext = true;
            } else if (cursorState.getResult().getNoNextReason().isLimitReached()) {
                // Stop if any has reached limit.
                return Collections.emptyList();
            }
        }
        if (anyHasNext) {
            // Result states are all those that share the minimum next position,
            // whose bitmaps need to be merged to produce the next stream element.
            final List<MergeCursorState<IndexEntry>> resultStates = new ArrayList<>();
            long nextPosition = Long.MAX_VALUE;
            for (MergeCursorState<IndexEntry> cursorState : cursorStates) {
                if (cursorState.getResult().hasNext()) {
                    final IndexEntry indexEntry = cursorState.getResult().get();
                    final Tuple indexKey = indexEntry.getKey();
                    final long position = indexKey.getLong(indexKey.size() - 1);
                    if (nextPosition > position) {
                        resultStates.clear();
                        nextPosition = position;
                    }
                    if (nextPosition == position) {
                        resultStates.add(cursorState);
                    }
                }
            }
            return resultStates;
        } else {
            return Collections.emptyList();
        }
    });
}
Also used : MergeCursorState(com.apple.foundationdb.record.provider.foundationdb.cursors.MergeCursorState) ArrayList(java.util.ArrayList) IndexEntry(com.apple.foundationdb.record.IndexEntry) Tuple(com.apple.foundationdb.tuple.Tuple) Nonnull(javax.annotation.Nonnull)

Example 67 with IndexEntry

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

the class ComposedBitmapIndexCursor method getNextResult.

@Nonnull
@Override
protected IndexEntry getNextResult(@Nonnull List<MergeCursorState<IndexEntry>> resultStates) {
    final List<MergeCursorState<IndexEntry>> cursorStates = getCursorStates();
    final IndexEntry firstEntry = resultStates.get(0).getResult().get();
    final int size = firstEntry.getValue().getBytes(0).length;
    final List<byte[]> bitmaps = new ArrayList<>(cursorStates.size());
    for (MergeCursorState<IndexEntry> cursorState : cursorStates) {
        if (resultStates.contains(cursorState)) {
            byte[] bitmap = cursorState.getResult().get().getValue().getBytes(0);
            if (bitmap.length != size) {
                throw new RecordCoreException("Index bitmaps are not all the same size");
            }
            bitmaps.add(bitmap);
        } else {
            bitmaps.add(null);
        }
    }
    final byte[] composed = composer.compose(bitmaps, size);
    return new IndexEntry(firstEntry.getIndex(), firstEntry.getKey(), Tuple.fromList(Collections.singletonList(composed)));
}
Also used : MergeCursorState(com.apple.foundationdb.record.provider.foundationdb.cursors.MergeCursorState) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) ArrayList(java.util.ArrayList) IndexEntry(com.apple.foundationdb.record.IndexEntry) Nonnull(javax.annotation.Nonnull)

Example 68 with IndexEntry

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

the class ComposedBitmapIndexQueryPlan method executePlan.

@Nonnull
@Override
public <M extends Message> RecordCursor<QueryResult> executePlan(@Nonnull final FDBRecordStoreBase<M> store, @Nonnull final EvaluationContext context, @Nullable final byte[] continuation, @Nonnull final ExecuteProperties executeProperties) {
    final ExecuteProperties scanExecuteProperties = executeProperties.getSkip() > 0 ? executeProperties.clearSkipAndAdjustLimit() : executeProperties;
    final List<Function<byte[], RecordCursor<IndexEntry>>> cursorFunctions = indexPlans.stream().map(RecordQueryCoveringIndexPlan::getIndexPlan).map(scan -> (Function<byte[], RecordCursor<IndexEntry>>) childContinuation -> scan.executeEntries(store, context, childContinuation, scanExecuteProperties)).collect(Collectors.toList());
    return ComposedBitmapIndexCursor.create(cursorFunctions, composer, continuation, store.getTimer()).filter(indexEntry -> indexEntry.getValue().get(0) != null).map(indexPlans.get(0).indexEntryToQueriedRecord(store)).map(QueryResult::of);
}
Also used : IndexEntry(com.apple.foundationdb.record.IndexEntry) RecordQueryPlanWithNoChildren(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithNoChildren) Arrays(java.util.Arrays) QueryResult(com.apple.foundationdb.record.query.plan.plans.QueryResult) StoreTimer(com.apple.foundationdb.record.provider.common.StoreTimer) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Function(java.util.function.Function) PlanHashable(com.apple.foundationdb.record.PlanHashable) ArrayList(java.util.ArrayList) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) ImmutableList(com.google.common.collect.ImmutableList) AliasMap(com.apple.foundationdb.record.query.plan.temp.AliasMap) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) FDBRecordStoreBase(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) Set(java.util.Set) Collectors(java.util.stream.Collectors) QueriedValue(com.apple.foundationdb.record.query.predicates.QueriedValue) RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) Objects(java.util.Objects) Value(com.apple.foundationdb.record.query.predicates.Value) RecordQueryCoveringIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryCoveringIndexPlan) List(java.util.List) CorrelationIdentifier(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) ObjectPlanHash(com.apple.foundationdb.record.ObjectPlanHash) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) API(com.apple.foundationdb.annotation.API) PlannerGraph(com.apple.foundationdb.record.query.plan.temp.explain.PlannerGraph) VisibleForTesting(com.google.common.annotations.VisibleForTesting) NodeInfo(com.apple.foundationdb.record.query.plan.temp.explain.NodeInfo) AvailableFields(com.apple.foundationdb.record.query.plan.AvailableFields) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) Function(java.util.function.Function) QueryResult(com.apple.foundationdb.record.query.plan.plans.QueryResult) IndexEntry(com.apple.foundationdb.record.IndexEntry) RecordQueryCoveringIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryCoveringIndexPlan) Nonnull(javax.annotation.Nonnull)

Example 69 with IndexEntry

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

the class QueryPlanUtils method getCoveringIndexEntryToPartialRecordFunction.

/**
 * The method to get a function from an {@link IndexEntry} to a {@link FDBQueriedRecord} representing a partial record.
 */
@SuppressWarnings("unchecked")
public static <M extends Message> Function<IndexEntry, FDBQueriedRecord<M>> getCoveringIndexEntryToPartialRecordFunction(@Nonnull final FDBRecordStoreBase<M> store, @Nonnull final String recordTypeName, @Nonnull final String indexName, @Nonnull final IndexKeyValueToPartialRecord toRecord, @Nonnull final IndexScanType scanType) {
    final RecordMetaData metaData = store.getRecordMetaData();
    final RecordType recordType = metaData.getRecordType(recordTypeName);
    final Index index = metaData.getIndex(indexName);
    final Descriptors.Descriptor recordDescriptor = recordType.getDescriptor();
    boolean hasPrimaryKey = scanType != IndexScanType.BY_GROUP && scanType != IndexScanType.BY_LUCENE_AUTO_COMPLETE && scanType != IndexScanType.BY_LUCENE_SPELLCHECK;
    return indexEntry -> store.coveredIndexQueriedRecord(index, indexEntry, recordType, (M) toRecord.toRecord(recordDescriptor, indexEntry), hasPrimaryKey);
}
Also used : IndexEntry(com.apple.foundationdb.record.IndexEntry) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) IndexScanType(com.apple.foundationdb.record.IndexScanType) RecordType(com.apple.foundationdb.record.metadata.RecordType) IndexKeyValueToPartialRecord(com.apple.foundationdb.record.query.plan.IndexKeyValueToPartialRecord) Index(com.apple.foundationdb.record.metadata.Index) Descriptors(com.google.protobuf.Descriptors) FDBQueriedRecord(com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord) Message(com.google.protobuf.Message) Nonnull(javax.annotation.Nonnull) Function(java.util.function.Function) FDBRecordStoreBase(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordType(com.apple.foundationdb.record.metadata.RecordType) Index(com.apple.foundationdb.record.metadata.Index) Descriptors(com.google.protobuf.Descriptors)

Example 70 with IndexEntry

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

the class StandardIndexMaintainer method validateMissingEntries.

/**
 * Validate entries in the index. It scans the records and checks if the index entries associated with each record
 * exist. Note that it may not work for indexes on synthetic record types (e.g., join indexes).
 * @param continuation any continuation from a previous validation invocation
 * @param scanProperties skip, limit and other properties of the validation
 * @return a cursor over records that have no associated index entries including the reason
 */
@Nonnull
protected RecordCursor<InvalidIndexEntry> validateMissingEntries(@Nullable byte[] continuation, @Nonnull ScanProperties scanProperties) {
    final Collection<RecordType> recordTypes = state.store.getRecordMetaData().recordTypesForIndex(state.index);
    final FDBRecordStoreBase.PipelineSizer pipelineSizer = state.store.getPipelineSizer();
    return RecordCursor.flatMapPipelined(cont -> state.store.scanRecords(TupleRange.ALL, cont, scanProperties).filter(rec -> recordTypes.contains(rec.getRecordType())), (record, cont) -> {
        List<IndexEntry> filteredIndexEntries = filteredIndexEntries(record);
        return RecordCursor.fromList(filteredIndexEntries == null ? Collections.emptyList() : filteredIndexEntries.stream().map(indexEntryWithoutPrimaryKey -> new IndexEntry(indexEntryWithoutPrimaryKey.getIndex(), indexEntryKey(indexEntryWithoutPrimaryKey.getKey(), record.getPrimaryKey()), indexEntryWithoutPrimaryKey.getValue())).map(indexEntry -> Pair.of(indexEntry, record)).collect(Collectors.toList()), cont);
    }, continuation, pipelineSizer.getPipelineSize(PipelineOperation.RECORD_FUNCTION)).filterAsync(indexEntryRecordPair -> {
        final byte[] keyBytes = state.indexSubspace.pack(indexEntryRecordPair.getLeft().getKey());
        return state.transaction.get(keyBytes).thenApply(Objects::isNull);
    }, pipelineSizer.getPipelineSize(PipelineOperation.INDEX_ASYNC_FILTER)).map(indexEntryKeyRecordPair -> InvalidIndexEntry.newMissing(indexEntryKeyRecordPair.getLeft(), indexEntryKeyRecordPair.getRight()));
}
Also used : IndexEntry(com.apple.foundationdb.record.IndexEntry) LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) IndexMaintainerState(com.apple.foundationdb.record.provider.foundationdb.IndexMaintainerState) FDBRecord(com.apple.foundationdb.record.provider.foundationdb.FDBRecord) LoggerFactory(org.slf4j.LoggerFactory) Subspace(com.apple.foundationdb.subspace.Subspace) Transaction(com.apple.foundationdb.Transaction) IndexScanType(com.apple.foundationdb.record.IndexScanType) Tuple(com.apple.foundationdb.tuple.Tuple) Range(com.apple.foundationdb.Range) KeyValueLogMessage(com.apple.foundationdb.record.logging.KeyValueLogMessage) Pair(org.apache.commons.lang3.tuple.Pair) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) PipelineOperation(com.apple.foundationdb.record.PipelineOperation) RecordIndexUniquenessViolation(com.apple.foundationdb.record.RecordIndexUniquenessViolation) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) FDBExceptions(com.apple.foundationdb.record.provider.foundationdb.FDBExceptions) FDBRecordStoreBase(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase) QueryToKeyMatcher(com.apple.foundationdb.record.query.QueryToKeyMatcher) ByteArrayUtil(com.apple.foundationdb.tuple.ByteArrayUtil) FDBIndexableRecord(com.apple.foundationdb.record.provider.foundationdb.FDBIndexableRecord) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) KeyValue(com.apple.foundationdb.KeyValue) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) Collection(java.util.Collection) Collectors(java.util.stream.Collectors) TupleRange(com.apple.foundationdb.record.TupleRange) Objects(java.util.Objects) KeyValueCursor(com.apple.foundationdb.record.provider.foundationdb.KeyValueCursor) List(java.util.List) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) API(com.apple.foundationdb.annotation.API) SplitHelper.unpackKey(com.apple.foundationdb.record.provider.foundationdb.SplitHelper.unpackKey) IndexMaintainer(com.apple.foundationdb.record.provider.foundationdb.IndexMaintainer) IndexMaintenanceFilter(com.apple.foundationdb.record.provider.foundationdb.IndexMaintenanceFilter) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) KeyWithValueExpression(com.apple.foundationdb.record.metadata.expressions.KeyWithValueExpression) IndexOperation(com.apple.foundationdb.record.provider.foundationdb.IndexOperation) CompletableFuture(java.util.concurrent.CompletableFuture) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) RangeSet(com.apple.foundationdb.async.RangeSet) Function(java.util.function.Function) CursorStreamingMode(com.apple.foundationdb.record.CursorStreamingMode) ArrayList(java.util.ArrayList) Key(com.apple.foundationdb.record.metadata.Key) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) ScanProperties(com.apple.foundationdb.record.ScanProperties) IndexRecordFunction(com.apple.foundationdb.record.metadata.IndexRecordFunction) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) IndexOperationResult(com.apple.foundationdb.record.provider.foundationdb.IndexOperationResult) MoreAsyncUtil(com.apple.foundationdb.async.MoreAsyncUtil) IsolationLevel(com.apple.foundationdb.record.IsolationLevel) Logger(org.slf4j.Logger) Executor(java.util.concurrent.Executor) RecordType(com.apple.foundationdb.record.metadata.RecordType) AsyncIterable(com.apple.foundationdb.async.AsyncIterable) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) Collections(java.util.Collections) RecordType(com.apple.foundationdb.record.metadata.RecordType) IndexEntry(com.apple.foundationdb.record.IndexEntry) FDBRecordStoreBase(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase) Nonnull(javax.annotation.Nonnull)

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