Search in sources :

Example 46 with TupleRange

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

the class RecordQueryScanPlan method rewritePlannerGraph.

/**
 * Rewrite the planner graph for better visualization of a query scan plan.
 * @param childGraphs planner graphs of children expression that already have been computed
 * @return the rewritten planner graph that models scanned storage as a separate node that is connected to the
 *         actual scan plan node.
 */
@Nonnull
@Override
public PlannerGraph rewritePlannerGraph(@Nonnull List<? extends PlannerGraph> childGraphs) {
    Verify.verify(childGraphs.isEmpty());
    @Nullable final TupleRange tupleRange = comparisons.toTupleRangeWithoutContext();
    final ImmutableList.Builder<String> detailsBuilder = ImmutableList.builder();
    final ImmutableMap.Builder<String, Attribute> additionalAttributes = ImmutableMap.builder();
    if (tupleRange != null) {
        detailsBuilder.add("range: " + tupleRange.getLowEndpoint().toString(false) + "{{low}}, {{high}}" + tupleRange.getHighEndpoint().toString(true));
        additionalAttributes.put("low", Attribute.gml(tupleRange.getLow() == null ? "-∞" : tupleRange.getLow().toString()));
        additionalAttributes.put("high", Attribute.gml(tupleRange.getHigh() == null ? "∞" : tupleRange.getHigh().toString()));
    } else {
        detailsBuilder.add("comparisons: {{comparisons}}");
        additionalAttributes.put("comparisons", Attribute.gml(comparisons.toString()));
    }
    if (reverse) {
        detailsBuilder.add("direction: {{direction}}");
        additionalAttributes.put("direction", Attribute.gml("reversed"));
    }
    final PlannerGraph.DataNodeWithInfo dataNodeWithInfo;
    if (getRecordTypes() == null) {
        dataNodeWithInfo = new PlannerGraph.DataNodeWithInfo(NodeInfo.BASE_DATA, ImmutableList.of("ALL"));
    } else {
        dataNodeWithInfo = new PlannerGraph.DataNodeWithInfo(NodeInfo.BASE_DATA, ImmutableList.of("record types: {{types}}"), ImmutableMap.of("types", Attribute.gml(getRecordTypes().stream().map(Attribute::gml).collect(ImmutableList.toImmutableList()))));
    }
    return PlannerGraph.fromNodeAndChildGraphs(new PlannerGraph.OperatorNodeWithInfo(this, NodeInfo.SCAN_OPERATOR, detailsBuilder.build(), additionalAttributes.build()), ImmutableList.of(PlannerGraph.fromNodeAndChildGraphs(dataNodeWithInfo, childGraphs)));
}
Also used : Attribute(com.apple.foundationdb.record.query.plan.temp.explain.Attribute) ImmutableList(com.google.common.collect.ImmutableList) TupleRange(com.apple.foundationdb.record.TupleRange) PlannerGraph(com.apple.foundationdb.record.query.plan.temp.explain.PlannerGraph) Nullable(javax.annotation.Nullable) ImmutableMap(com.google.common.collect.ImmutableMap) Nonnull(javax.annotation.Nonnull)

Example 47 with TupleRange

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

the class RankedSetIndexHelper method rankRangeToScoreRange.

@Nonnull
public static CompletableFuture<TupleRange> rankRangeToScoreRange(@Nonnull IndexMaintainerState state, int groupPrefixSize, @Nonnull Subspace rankSubspace, @Nonnull RankedSet.Config config, @Nonnull TupleRange rankRange) {
    final Tuple prefix = groupPrefix(groupPrefixSize, rankRange, rankSubspace);
    if (prefix != null) {
        rankSubspace = rankSubspace.subspace(prefix);
    }
    // Map low and high ranks to scores and scan main index with those.
    Number lowRankNum = extractRank(groupPrefixSize, rankRange.getLow());
    boolean startFromBeginning = lowRankNum == null || lowRankNum.longValue() < 0L;
    EndpointType lowEndpoint = startFromBeginning ? EndpointType.RANGE_INCLUSIVE : rankRange.getLowEndpoint();
    Number highRankNum = extractRank(groupPrefixSize, rankRange.getHigh());
    EndpointType highEndpoint = rankRange.getHighEndpoint();
    if (highRankNum != null && (highRankNum.longValue() < 0L || highEndpoint == EndpointType.RANGE_EXCLUSIVE && highRankNum.longValue() == 0L)) {
        // This range is below 0, so we know the range is empty without having to look.
        return CompletableFuture.completedFuture(null);
    }
    if (highRankNum != null && highEndpoint == EndpointType.RANGE_EXCLUSIVE && lowEndpoint == EndpointType.RANGE_EXCLUSIVE && highRankNum.equals(lowRankNum)) {
        // This range is exclusively empty.
        return CompletableFuture.completedFuture(null);
    }
    if (startFromBeginning && highRankNum == null) {
        // Scanning whole range, no need to convert any ranks.
        return CompletableFuture.completedFuture(TupleRange.allOf(prefix));
    }
    final RankedSet rankedSet = new InstrumentedRankedSet(state, rankSubspace, config);
    return init(state, rankedSet).thenCompose(v -> {
        CompletableFuture<Tuple> lowScoreFuture = scoreForRank(state, rankedSet, startFromBeginning ? 0L : lowRankNum, null);
        CompletableFuture<Tuple> highScoreFuture = scoreForRank(state, rankedSet, highRankNum, null);
        return lowScoreFuture.thenCombine(highScoreFuture, (lowScore, highScore) -> {
            // from low until the end.
            if (lowScore == null) {
                return null;
            }
            EndpointType adjustedHighEndpoint = highScore != null ? highEndpoint : prefix != null ? EndpointType.RANGE_INCLUSIVE : EndpointType.TREE_END;
            TupleRange scoreRange = new TupleRange(lowScore, highScore, lowEndpoint, adjustedHighEndpoint);
            if (prefix != null) {
                scoreRange = scoreRange.prepend(prefix);
            }
            return scoreRange;
        });
    });
}
Also used : EndpointType(com.apple.foundationdb.record.EndpointType) RankedSet(com.apple.foundationdb.async.RankedSet) TupleRange(com.apple.foundationdb.record.TupleRange) Tuple(com.apple.foundationdb.tuple.Tuple) Nonnull(javax.annotation.Nonnull)

Example 48 with TupleRange

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

the class TimeWindowLeaderboardIndexMaintainer method negateScoreRange.

/**
 * Negate the score part of the given range, which is after the group prefix and before the timestamp and any
 * other tiebreakers.
 * @param range the range of scores in normal order
 * @return a range with scores negated so that they sort in reverse order
 */
protected TupleRange negateScoreRange(@Nonnull TupleRange range) {
    final int groupPrefixSize = getGroupingCount();
    Tuple low = range.getLow();
    Tuple high = range.getHigh();
    EndpointType lowEndpoint = range.getLowEndpoint();
    EndpointType highEndpoint = range.getHighEndpoint();
    if (low == null || low.size() < groupPrefixSize) {
        if (lowEndpoint == EndpointType.TREE_START) {
            lowEndpoint = EndpointType.TREE_END;
        }
    } else {
        low = negateScoreForHighScoreFirst(low, groupPrefixSize);
    }
    if (high == null || high.size() < groupPrefixSize) {
        if (lowEndpoint == EndpointType.TREE_END) {
            lowEndpoint = EndpointType.TREE_START;
        }
    } else {
        high = negateScoreForHighScoreFirst(high, groupPrefixSize);
    }
    return new TupleRange(high, low, highEndpoint, lowEndpoint);
}
Also used : EndpointType(com.apple.foundationdb.record.EndpointType) TupleRange(com.apple.foundationdb.record.TupleRange) Tuple(com.apple.foundationdb.tuple.Tuple)

Aggregations

TupleRange (com.apple.foundationdb.record.TupleRange)48 Tuple (com.apple.foundationdb.tuple.Tuple)29 Nonnull (javax.annotation.Nonnull)28 Message (com.google.protobuf.Message)21 Index (com.apple.foundationdb.record.metadata.Index)16 Test (org.junit.jupiter.api.Test)16 ScanProperties (com.apple.foundationdb.record.ScanProperties)15 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)14 Nullable (javax.annotation.Nullable)14 ExecuteProperties (com.apple.foundationdb.record.ExecuteProperties)11 IndexEntry (com.apple.foundationdb.record.IndexEntry)11 List (java.util.List)11 IsolationLevel (com.apple.foundationdb.record.IsolationLevel)10 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)10 RecordCursor (com.apple.foundationdb.record.RecordCursor)10 IndexScanType (com.apple.foundationdb.record.IndexScanType)9 CompletableFuture (java.util.concurrent.CompletableFuture)9 Range (com.apple.foundationdb.Range)8 API (com.apple.foundationdb.annotation.API)8 AsyncUtil (com.apple.foundationdb.async.AsyncUtil)8