Search in sources :

Example 1 with TopologicalOrderIterator

use of org.apache.calcite.util.graph.TopologicalOrderIterator in project calcite by apache.

the class CalcRelSplitter method computeTopologicalOrdering.

/**
 * Computes the order in which to visit expressions, so that we decide the
 * level of an expression only after the levels of lower expressions have
 * been decided.
 *
 * <p>First, we need to ensure that an expression is visited after all of
 * its inputs.
 *
 * <p>Further, if the expression is a member of a cohort, we need to visit
 * it after the inputs of all other expressions in that cohort. With this
 * condition, expressions in the same cohort will very likely end up in the
 * same level.
 *
 * <p>Note that if there are no cohorts, the expressions from the
 * {@link RexProgram} are already in a suitable order. We perform the
 * topological sort just to ensure that the code path is well-trodden.
 *
 * @param exprs   Expressions
 * @param cohorts List of cohorts, each of which is a set of expr ordinals
 * @return Expression ordinals in topological order
 */
private List<Integer> computeTopologicalOrdering(RexNode[] exprs, List<Set<Integer>> cohorts) {
    final DirectedGraph<Integer, DefaultEdge> graph = DefaultDirectedGraph.create();
    for (int i = 0; i < exprs.length; i++) {
        graph.addVertex(i);
    }
    for (int i = 0; i < exprs.length; i++) {
        final RexNode expr = exprs[i];
        final Set<Integer> cohort = findCohort(cohorts, i);
        final Set<Integer> targets;
        if (cohort == null) {
            targets = Collections.singleton(i);
        } else {
            targets = cohort;
        }
        expr.accept(new RexVisitorImpl<Void>(true) {

            public Void visitLocalRef(RexLocalRef localRef) {
                for (Integer target : targets) {
                    graph.addEdge(localRef.getIndex(), target);
                }
                return null;
            }
        });
    }
    TopologicalOrderIterator<Integer, DefaultEdge> iter = new TopologicalOrderIterator<>(graph);
    final List<Integer> permutation = new ArrayList<>();
    while (iter.hasNext()) {
        permutation.add(iter.next());
    }
    return permutation;
}
Also used : ArrayList(java.util.ArrayList) DefaultEdge(org.apache.calcite.util.graph.DefaultEdge) TopologicalOrderIterator(org.apache.calcite.util.graph.TopologicalOrderIterator) RexLocalRef(org.apache.calcite.rex.RexLocalRef) RexNode(org.apache.calcite.rex.RexNode)

Example 2 with TopologicalOrderIterator

use of org.apache.calcite.util.graph.TopologicalOrderIterator in project beam by apache.

the class CalcRelSplitter method computeTopologicalOrdering.

/**
 * Computes the order in which to visit expressions, so that we decide the level of an expression
 * only after the levels of lower expressions have been decided.
 *
 * <p>First, we need to ensure that an expression is visited after all of its inputs.
 *
 * <p>Further, if the expression is a member of a cohort, we need to visit it after the inputs of
 * all other expressions in that cohort. With this condition, expressions in the same cohort will
 * very likely end up in the same level.
 *
 * <p>Note that if there are no cohorts, the expressions from the {@link RexProgram} are already
 * in a suitable order. We perform the topological sort just to ensure that the code path is
 * well-trodden.
 *
 * @param exprs Expressions
 * @param cohorts List of cohorts, each of which is a set of expr ordinals
 * @return Expression ordinals in topological order
 */
private static List<Integer> computeTopologicalOrdering(RexNode[] exprs, List<Set<Integer>> cohorts) {
    final DirectedGraph<Integer, DefaultEdge> graph = DefaultDirectedGraph.create();
    for (int i = 0; i < exprs.length; i++) {
        graph.addVertex(i);
    }
    for (int i = 0; i < exprs.length; i++) {
        final RexNode expr = exprs[i];
        final Set<Integer> cohort = findCohort(cohorts, i);
        final Set<Integer> targets;
        if (cohort == null) {
            targets = Collections.singleton(i);
        } else {
            targets = cohort;
        }
        expr.accept(new RexVisitorImpl<Void>(true) {

            @Override
            public Void visitLocalRef(RexLocalRef localRef) {
                for (Integer target : targets) {
                    graph.addEdge(localRef.getIndex(), target);
                }
                return null;
            }
        });
    }
    TopologicalOrderIterator<Integer, DefaultEdge> iter = new TopologicalOrderIterator<>(graph);
    final List<Integer> permutation = new ArrayList<>();
    while (iter.hasNext()) {
        permutation.add(iter.next());
    }
    return permutation;
}
Also used : ArrayList(java.util.ArrayList) DefaultEdge(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.graph.DefaultEdge) TopologicalOrderIterator(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.graph.TopologicalOrderIterator) RexLocalRef(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLocalRef) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)

Aggregations

ArrayList (java.util.ArrayList)2 RexLocalRef (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLocalRef)1 RexNode (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)1 DefaultEdge (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.graph.DefaultEdge)1 TopologicalOrderIterator (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.graph.TopologicalOrderIterator)1 RexLocalRef (org.apache.calcite.rex.RexLocalRef)1 RexNode (org.apache.calcite.rex.RexNode)1 DefaultEdge (org.apache.calcite.util.graph.DefaultEdge)1 TopologicalOrderIterator (org.apache.calcite.util.graph.TopologicalOrderIterator)1