Search in sources :

Example 1 with NetworkBuilder

use of com.google.common.graph.NetworkBuilder in project fdb-record-layer by FoundationDB.

the class ParameterRelationshipGraph method fromRecordQueryAndBindings.

/**
 * Derive a relationship graph from a {@link RecordQuery} and a set of pre-bound parameters in handing in
 * as a {@link Bindings} object.
 * <p>
 * Note that we do not derive additional relationships (yet). So for instance a query
 * </p>
 * <p>
 * {@code
 * ...
 * WHERE x < $p1 AND x = $p2 AND y < $p2 AND y = $p3
 * }
 * </p>
 * with pre-bindings {@code p1 -> 10, p2 -> 10, p3 -> 10} would result in a graph containing
 * <p>
 * {@code
 * p1 EQUALS p1
 * p1 EQUALS p2
 * p2 EQUALS p1
 * p2 EQUALS p2
 * p2 EQUALS p3
 * p3 EQUALS p2
 * p3 EQUALS p3
 * }
 * </p>
 * but it would not contain
 * <p>
 * {@code
 * p1 EQUALS p3
 * p3 EQUALS p1
 * }
 * </p>
 * @param recordQuery query
 * @param preBoundParameterBindings parameter bindings already known at planning time
 * @return a new {@link ParameterRelationshipGraph}
 */
@Nonnull
public static ParameterRelationshipGraph fromRecordQueryAndBindings(@Nonnull final RecordQuery recordQuery, @Nonnull final Bindings preBoundParameterBindings) {
    final QueryComponent filter = recordQuery.getFilter();
    final ImmutableNetwork.Builder<String, Relationship> networkBuilder = NetworkBuilder.directed().allowsSelfLoops(true).allowsParallelEdges(true).immutable();
    if (filter != null) {
        groupedComparisons(filter).flatMap(entry -> StreamSupport.stream(crossProduct(ImmutableList.of(entry.getValue(), entry.getValue())).spliterator(), false)).map(list -> Pair.of(list.get(0), list.get(1))).forEach(pair -> {
            final Comparisons.ComparisonWithParameter left = pair.getLeft();
            final Comparisons.ComparisonWithParameter right = pair.getRight();
            if (left.getParameter().equals(right.getParameter())) {
                Relationship.addEdge(networkBuilder, RelationshipType.EQUALS, left.getParameter(), right.getParameter());
                Relationship.addEdge(networkBuilder, RelationshipType.EQUALS, right.getParameter(), left.getParameter());
            } else if (// It is possible that some of the parameters are not pre-bound. That's not an error,
            preBoundParameterBindings.containsBinding(left.getParameter()) && preBoundParameterBindings.containsBinding(right.getParameter())) {
                // it just means we cannot establish any sort of relationship between them.
                final Object leftComparand = preBoundParameterBindings.get(left.getParameter());
                final Object rightComparand = preBoundParameterBindings.get(right.getParameter());
                if (Objects.equals(leftComparand, rightComparand)) {
                    Relationship.addEdge(networkBuilder, RelationshipType.EQUALS, left.getParameter(), right.getParameter());
                    Relationship.addEdge(networkBuilder, RelationshipType.EQUALS, right.getParameter(), left.getParameter());
                }
            }
        });
    }
    return new ParameterRelationshipGraph(networkBuilder.build());
}
Also used : BooleanComponent.groupedComparisons(com.apple.foundationdb.record.query.expressions.BooleanComponent.groupedComparisons) ImmutableSet(com.google.common.collect.ImmutableSet) NetworkBuilder(com.google.common.graph.NetworkBuilder) Set(java.util.Set) Bindings(com.apple.foundationdb.record.Bindings) Objects(java.util.Objects) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) ImmutableList(com.google.common.collect.ImmutableList) Pair(org.apache.commons.lang3.tuple.Pair) ImmutableNetwork(com.google.common.graph.ImmutableNetwork) CrossProduct.crossProduct(com.apple.foundationdb.record.query.combinatorics.CrossProduct.crossProduct) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) StreamSupport(java.util.stream.StreamSupport) API(com.apple.foundationdb.annotation.API) Network(com.google.common.graph.Network) Nonnull(javax.annotation.Nonnull) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) ImmutableNetwork(com.google.common.graph.ImmutableNetwork) BooleanComponent.groupedComparisons(com.apple.foundationdb.record.query.expressions.BooleanComponent.groupedComparisons) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) Nonnull(javax.annotation.Nonnull)

Aggregations

API (com.apple.foundationdb.annotation.API)1 Bindings (com.apple.foundationdb.record.Bindings)1 CrossProduct.crossProduct (com.apple.foundationdb.record.query.combinatorics.CrossProduct.crossProduct)1 BooleanComponent.groupedComparisons (com.apple.foundationdb.record.query.expressions.BooleanComponent.groupedComparisons)1 Comparisons (com.apple.foundationdb.record.query.expressions.Comparisons)1 QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 ImmutableNetwork (com.google.common.graph.ImmutableNetwork)1 Network (com.google.common.graph.Network)1 NetworkBuilder (com.google.common.graph.NetworkBuilder)1 Objects (java.util.Objects)1 Set (java.util.Set)1 StreamSupport (java.util.stream.StreamSupport)1 Nonnull (javax.annotation.Nonnull)1 Pair (org.apache.commons.lang3.tuple.Pair)1