>From Vijay Sarathy <[email protected]>:

Vijay Sarathy has uploaded this change for review. ( 
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19392 )


Change subject: [ASTERIXDB-3559][COMP] Add output document size at each 
operator in explain plan
......................................................................

[ASTERIXDB-3559][COMP] Add output document size at each operator in explain plan

- user model changes: yes
- storage format changes: no
- interface changes: no

Details:
Explain plans currently display cardinality, operator cost, and total cost at 
each
operator in the explain plan.

This patch adds the output document size to the above parameters to each 
operator in
the explain plan.

Ext-ref: MB-65102

Change-Id: I6a3e8ec8b904b34b96a055b19cd5e826246bd7a0
---
M 
hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/AbstractLogicalOperatorPrettyPrintVisitor.java
M 
hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EstimatedCostComputationVisitor.java
M 
hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitor.java
M 
hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
M 
hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/OperatorAnnotations.java
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
7 files changed, 283 insertions(+), 149 deletions(-)



  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb 
refs/changes/92/19392/1

diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
index 0861c01..9ca80cb 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
@@ -1129,6 +1129,8 @@
             return;
         op.getAnnotations().put(OperatorAnnotations.OP_OUTPUT_CARDINALITY,
                 (double) Math.round(plan.getJoinNode().getCardinality() * 100) 
/ 100);
+        op.getAnnotations().put(OperatorAnnotations.OP_OUTPUT_DOCSIZE,
+                (double) Math.round(plan.getJoinNode().getOutputSize() * 100) 
/ 100);
         op.getAnnotations().put(OperatorAnnotations.OP_COST_TOTAL,
                 (double) Math.round(plan.computeTotalCost() * 100) / 100);
         if (plan.IsScanNode()) {
diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EstimatedCostComputationVisitor.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EstimatedCostComputationVisitor.java
index 4874417..1e70fa7 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EstimatedCostComputationVisitor.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EstimatedCostComputationVisitor.java
@@ -21,7 +21,6 @@
 import java.util.Map;

 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.common.utils.Pair;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import org.apache.hyracks.algebricks.core.algebra.base.OperatorAnnotations;
@@ -66,330 +65,387 @@
 /**
  * A visitor that annotates an operator with its estimated cardinality and 
estimated cost.
  */
-public class EstimatedCostComputationVisitor implements 
ILogicalOperatorVisitor<Pair<Double, Double>, Double> {
+public class EstimatedCostComputationVisitor
+        implements 
ILogicalOperatorVisitor<EstimatedCostComputationVisitor.CardSizeCost, Double> {

     public EstimatedCostComputationVisitor() {
     }

     @Override
-    public Pair<Double, Double> visitAggregateOperator(AggregateOperator op, 
Double arg) throws AlgebricksException {
-        return annotate(this, op, arg);
-    }
-
-    @Override
-    public Pair<Double, Double> 
visitRunningAggregateOperator(RunningAggregateOperator op, Double arg)
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitAggregateOperator(AggregateOperator op, Double arg)
             throws AlgebricksException {
         return annotate(this, op, arg);
     }

     @Override
-    public Pair<Double, Double> 
visitEmptyTupleSourceOperator(EmptyTupleSourceOperator op, Double arg)
-            throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitRunningAggregateOperator(RunningAggregateOperator op,
+            Double arg) throws AlgebricksException {
+        return annotate(this, op, arg);
+    }
+
+    @Override
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitEmptyTupleSourceOperator(EmptyTupleSourceOperator op,
+            Double arg) throws AlgebricksException {
         // Empty tuple source operator sends an empty tuple to downstream 
operators.
-        return new Pair<>(0.0, 0.0);
+        return new EstimatedCostComputationVisitor.CardSizeCost(0.0, 0.0, 0.0);
     }

     @Override
-    public Pair<Double, Double> visitGroupByOperator(GroupByOperator op, 
Double arg) throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitGroupByOperator(GroupByOperator op, Double arg)
+            throws AlgebricksException {

         return annotateGroupByDistinct(op, arg);
     }

-    private Pair<Double, Double> annotateGroupByDistinct(ILogicalOperator op, 
Double arg) throws AlgebricksException {
+    private EstimatedCostComputationVisitor.CardSizeCost 
annotateGroupByDistinct(ILogicalOperator op, Double arg)
+            throws AlgebricksException {
         double groupByDistinctCost = 0.0;
-        Pair<Double, Double> cardCost = 
op.getInputs().get(0).getValue().accept(this, arg);
+        EstimatedCostComputationVisitor.CardSizeCost cardSizeCost =
+                op.getInputs().getFirst().getValue().accept(this, arg);

         for (Map.Entry<String, Object> anno : op.getAnnotations().entrySet()) {
             if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_OUTPUT_CARDINALITY)) {
-                cardCost.setFirst((Double) anno.getValue());
+                cardSizeCost.setCard((Double) anno.getValue());
             }
             if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_COST_LOCAL)) {
                 groupByDistinctCost = (double) anno.getValue();
             }
         }
-        double totalCost = cardCost.getSecond() + groupByDistinctCost;
-        op.getAnnotations().put(OperatorAnnotations.OP_COST_TOTAL, (double) 
Math.round(totalCost * 100) / 100);
-        cardCost.setSecond(totalCost);

-        return cardCost;
+        double totalCost = cardSizeCost.getCost() + groupByDistinctCost;
+        cardSizeCost.setCost(totalCost);
+        annotateOp(op, cardSizeCost);
+
+        return cardSizeCost;
     }

     @Override
-    public Pair<Double, Double> visitLimitOperator(LimitOperator op, Double 
arg) throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitLimitOperator(LimitOperator op, Double arg)
+            throws AlgebricksException {
         return annotate(this, op, arg);
     }

     @Override
-    public Pair<Double, Double> visitInnerJoinOperator(InnerJoinOperator op, 
Double arg) throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitInnerJoinOperator(InnerJoinOperator op, Double arg)
+            throws AlgebricksException {
         return visitInnerJoin(op, arg);
     }

     @Override
-    public Pair<Double, Double> 
visitLeftOuterJoinOperator(LeftOuterJoinOperator op, Double arg)
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitLeftOuterJoinOperator(LeftOuterJoinOperator op, Double arg)
             throws AlgebricksException {
         return visitLeftOuterUnnest(op, arg);
     }

     @Override
-    public Pair<Double, Double> 
visitNestedTupleSourceOperator(NestedTupleSourceOperator op, Double arg)
-            throws AlgebricksException {
-        Pair<Double, Double> cardCost = annotate(this, op, arg);
-        return op.getDataSourceReference().getValue().getOperatorTag() == 
LogicalOperatorTag.SUBPLAN ? cardCost
-                : new Pair<>(0.0, 0.0);
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitNestedTupleSourceOperator(NestedTupleSourceOperator op,
+            Double arg) throws AlgebricksException {
+        EstimatedCostComputationVisitor.CardSizeCost cardSizeCost = 
annotate(this, op, arg);
+        return op.getDataSourceReference().getValue().getOperatorTag() == 
LogicalOperatorTag.SUBPLAN ? cardSizeCost
+                : new EstimatedCostComputationVisitor.CardSizeCost(0.0, 0.0, 
0.0);
     }

     @Override
-    public Pair<Double, Double> visitOrderOperator(OrderOperator op, Double 
arg) throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitOrderOperator(OrderOperator op, Double arg)
+            throws AlgebricksException {
         double orderCost = 0.0;
-        Pair<Double, Double> cardCost = 
op.getInputs().get(0).getValue().accept(this, arg);
+        EstimatedCostComputationVisitor.CardSizeCost cardSizeCost =
+                op.getInputs().getFirst().getValue().accept(this, arg);

         for (Map.Entry<String, Object> anno : op.getAnnotations().entrySet()) {
             if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_COST_LOCAL)) {
                 orderCost = (double) anno.getValue();
             }
         }
-        double totalCost = cardCost.getSecond() + orderCost;
+
+        double totalCost = cardSizeCost.getCost() + orderCost;
         op.getAnnotations().put(OperatorAnnotations.OP_COST_TOTAL, (double) 
Math.round(totalCost * 100) / 100);
-        op.getAnnotations().put(OperatorAnnotations.OP_OUTPUT_CARDINALITY,
-                (double) Math.round(cardCost.getFirst() * 100) / 100);
-        cardCost.setSecond(totalCost);
+        cardSizeCost.setCost(totalCost);
+        annotateOp(op, cardSizeCost);

-        return cardCost;
+        return cardSizeCost;
     }

     @Override
-    public Pair<Double, Double> visitAssignOperator(AssignOperator op, Double 
arg) throws AlgebricksException {
-        return annotate(this, op, arg);
-    }
-
-    @Override
-    public Pair<Double, Double> visitWindowOperator(WindowOperator op, Double 
arg) throws AlgebricksException {
-        return annotate(this, op, arg);
-    }
-
-    @Override
-    public Pair<Double, Double> visitSelectOperator(SelectOperator op, Double 
arg) throws AlgebricksException {
-        Pair<Double, Double> cardCost = 
op.getInputs().get(0).getValue().accept(this, arg);
-        for (Map.Entry<String, Object> anno : op.getAnnotations().entrySet()) {
-            if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_OUTPUT_CARDINALITY)) {
-                cardCost.setFirst((Double) anno.getValue());
-            } else if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_COST_TOTAL)) {
-                cardCost.setSecond((Double) anno.getValue());
-            }
-        }
-
-        return cardCost;
-    }
-
-    @Override
-    public Pair<Double, Double> visitDelegateOperator(DelegateOperator op, 
Double arg) throws AlgebricksException {
-        return annotate(this, op, arg);
-    }
-
-    @Override
-    public Pair<Double, Double> visitProjectOperator(ProjectOperator op, 
Double arg) throws AlgebricksException {
-        return annotate(this, op, arg);
-    }
-
-    @Override
-    public Pair<Double, Double> visitReplicateOperator(ReplicateOperator op, 
Double arg) throws AlgebricksException {
-        return annotate(this, op, arg);
-    }
-
-    @Override
-    public Pair<Double, Double> visitSplitOperator(SplitOperator op, Double 
arg) throws AlgebricksException {
-        return annotate(this, op, arg);
-    }
-
-    @Override
-    public Pair<Double, Double> visitSwitchOperator(SwitchOperator op, Double 
arg) throws AlgebricksException {
-        return annotate(this, op, arg);
-    }
-
-    @Override
-    public Pair<Double, Double> visitMaterializeOperator(MaterializeOperator 
op, Double arg)
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitAssignOperator(AssignOperator op, Double arg)
             throws AlgebricksException {
         return annotate(this, op, arg);
     }

     @Override
-    public Pair<Double, Double> visitScriptOperator(ScriptOperator op, Double 
arg) throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitWindowOperator(WindowOperator op, Double arg)
+            throws AlgebricksException {
         return annotate(this, op, arg);
     }

     @Override
-    public Pair<Double, Double> visitSubplanOperator(SubplanOperator op, 
Double arg) throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitSelectOperator(SelectOperator op, Double arg)
+            throws AlgebricksException {
+        EstimatedCostComputationVisitor.CardSizeCost cardSizeCost =
+                op.getInputs().getFirst().getValue().accept(this, arg);
+        for (Map.Entry<String, Object> anno : op.getAnnotations().entrySet()) {
+            if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_OUTPUT_CARDINALITY)) {
+                cardSizeCost.setCard((Double) anno.getValue());
+            } else if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_COST_TOTAL)) {
+                cardSizeCost.setCost((Double) anno.getValue());
+            }
+        }
+
+        annotateOp(op, cardSizeCost);
+        return cardSizeCost;
+    }
+
+    @Override
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitDelegateOperator(DelegateOperator op, Double arg)
+            throws AlgebricksException {
         return annotate(this, op, arg);
     }

     @Override
-    public Pair<Double, Double> visitSinkOperator(SinkOperator op, Double arg) 
throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitProjectOperator(ProjectOperator op, Double arg)
+            throws AlgebricksException {
         return annotate(this, op, arg);
     }

     @Override
-    public Pair<Double, Double> visitUnionOperator(UnionAllOperator op, Double 
arg) throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitReplicateOperator(ReplicateOperator op, Double arg)
+            throws AlgebricksException {
+        return annotate(this, op, arg);
+    }
+
+    @Override
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitSplitOperator(SplitOperator op, Double arg)
+            throws AlgebricksException {
+        return annotate(this, op, arg);
+    }
+
+    @Override
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitSwitchOperator(SwitchOperator op, Double arg)
+            throws AlgebricksException {
+        return annotate(this, op, arg);
+    }
+
+    @Override
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitMaterializeOperator(MaterializeOperator op, Double arg)
+            throws AlgebricksException {
+        return annotate(this, op, arg);
+    }
+
+    @Override
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitScriptOperator(ScriptOperator op, Double arg)
+            throws AlgebricksException {
+        return annotate(this, op, arg);
+    }
+
+    @Override
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitSubplanOperator(SubplanOperator op, Double arg)
+            throws AlgebricksException {
+        return annotate(this, op, arg);
+    }
+
+    @Override
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitSinkOperator(SinkOperator op, Double arg)
+            throws AlgebricksException {
+        return annotate(this, op, arg);
+    }
+
+    @Override
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitUnionOperator(UnionAllOperator op, Double arg)
+            throws AlgebricksException {
         // Needs more work.
         return annotate(this, op, arg);
     }

     @Override
-    public Pair<Double, Double> visitUnnestOperator(UnnestOperator op, Double 
arg) throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitUnnestOperator(UnnestOperator op, Double arg)
+            throws AlgebricksException {
         return annotate(this, op, arg);
     }

     @Override
-    public Pair<Double, Double> 
visitLeftOuterUnnestOperator(LeftOuterUnnestOperator op, Double arg)
-            throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitLeftOuterUnnestOperator(LeftOuterUnnestOperator op,
+            Double arg) throws AlgebricksException {
         return visitLeftOuterUnnest(op, arg);
     }

     @Override
-    public Pair<Double, Double> visitUnnestMapOperator(UnnestMapOperator op, 
Double arg) throws AlgebricksException {
-        Pair<Double, Double> cardCost = new Pair<>(0.0, 0.0);
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitUnnestMapOperator(UnnestMapOperator op, Double arg)
+            throws AlgebricksException {
+        EstimatedCostComputationVisitor.CardSizeCost cardSizeCost =
+                new EstimatedCostComputationVisitor.CardSizeCost(0.0, 0.0, 
0.0);

         for (Map.Entry<String, Object> anno : op.getAnnotations().entrySet()) {
             if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_OUTPUT_CARDINALITY)) {
-                cardCost.setFirst((Double) anno.getValue());
+                cardSizeCost.setCard((Double) anno.getValue());
+            } else if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_OUTPUT_DOCSIZE)) {
+                cardSizeCost.setSize((Double) anno.getValue());
             } else if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_COST_TOTAL)) {
-                cardCost.setSecond((Double) anno.getValue());
+                cardSizeCost.setCost((Double) anno.getValue());
             }
         }

-        return cardCost;
+        annotateOp(op, cardSizeCost);
+        return cardSizeCost;
     }

     @Override
-    public Pair<Double, Double> 
visitLeftOuterUnnestMapOperator(LeftOuterUnnestMapOperator op, Double arg)
-            throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitLeftOuterUnnestMapOperator(LeftOuterUnnestMapOperator op,
+            Double arg) throws AlgebricksException {
         return visitLeftOuterUnnest(op, arg);
     }

     @Override
-    public Pair<Double, Double> visitDataScanOperator(DataSourceScanOperator 
op, Double arg)
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitDataScanOperator(DataSourceScanOperator op, Double arg)
             throws AlgebricksException {
-        Pair<Double, Double> cardCost = new Pair<>(0.0, 0.0);
+        EstimatedCostComputationVisitor.CardSizeCost cardSizeCost =
+                new EstimatedCostComputationVisitor.CardSizeCost(0.0, 0.0, 
0.0);

         for (Map.Entry<String, Object> anno : op.getAnnotations().entrySet()) {
             if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_OUTPUT_CARDINALITY)) {
                 if (op.getSelectCondition() != null) {
-                    cardCost.setFirst((Double) anno.getValue());
+                    cardSizeCost.setCard((Double) anno.getValue());
                 }
             } else if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_INPUT_CARDINALITY)) {
                 if (op.getSelectCondition() == null) {
-                    cardCost.setFirst((Double) anno.getValue());
+                    cardSizeCost.setCard((Double) anno.getValue());
                 }
+            } else if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_OUTPUT_DOCSIZE)) {
+                cardSizeCost.setSize((Double) anno.getValue());
             } else if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_COST_TOTAL)) {
-                cardCost.setSecond((Double) anno.getValue());
+                cardSizeCost.setCost((Double) anno.getValue());
             }
         }

-        return cardCost;
+        annotateOp(op, cardSizeCost);
+        return cardSizeCost;
     }

     @Override
-    public Pair<Double, Double> visitDistinctOperator(DistinctOperator op, 
Double arg) throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitDistinctOperator(DistinctOperator op, Double arg)
+            throws AlgebricksException {

         return annotateGroupByDistinct(op, arg);
     }

     @Override
-    public Pair<Double, Double> visitExchangeOperator(ExchangeOperator op, 
Double arg) throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitExchangeOperator(ExchangeOperator op, Double arg)
+            throws AlgebricksException {
         double exchCost = 0;
         if (arg != null) {
             exchCost = arg;
         }

-        Pair<Double, Double> cardCost = 
op.getInputs().get(0).getValue().accept(this, arg);
+        EstimatedCostComputationVisitor.CardSizeCost cardSizeCost =
+                op.getInputs().getFirst().getValue().accept(this, arg);
         if (exchCost != 0) {
             op.getAnnotations().put(OperatorAnnotations.OP_COST_LOCAL, 
(double) Math.round(exchCost * 100) / 100);
             op.getAnnotations().put(OperatorAnnotations.OP_COST_TOTAL,
-                    (double) Math.round((exchCost + cardCost.getSecond()) * 
100) / 100);
+                    (double) Math.round((exchCost + cardSizeCost.getCost()) * 
100) / 100);
         } else {
             op.getAnnotations().put(OperatorAnnotations.OP_COST_LOCAL, 0.0);
             op.getAnnotations().put(OperatorAnnotations.OP_COST_TOTAL,
-                    (double) Math.round(cardCost.getSecond() * 100) / 100);
+                    (double) Math.round(cardSizeCost.getCost() * 100) / 100);
         }
         op.getAnnotations().put(OperatorAnnotations.OP_OUTPUT_CARDINALITY,
-                (double) Math.round(cardCost.getFirst() * 100) / 100);
-        return cardCost;
+                (double) Math.round(cardSizeCost.getCard() * 100) / 100);
+        op.getAnnotations().put(OperatorAnnotations.OP_OUTPUT_DOCSIZE,
+                (double) Math.round(cardSizeCost.getSize() * 100) / 100);
+
+        annotateOp(op, cardSizeCost);
+        return cardSizeCost;
     }

     @Override
-    public Pair<Double, Double> visitWriteOperator(WriteOperator op, Double 
arg) throws AlgebricksException {
-        return annotate(this, op, arg);
-    }
-
-    @Override
-    public Pair<Double, Double> 
visitDistributeResultOperator(DistributeResultOperator op, Double arg)
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitWriteOperator(WriteOperator op, Double arg)
             throws AlgebricksException {
         return annotate(this, op, arg);
     }

     @Override
-    public Pair<Double, Double> 
visitInsertDeleteUpsertOperator(InsertDeleteUpsertOperator op, Double arg)
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitDistributeResultOperator(DistributeResultOperator op,
+            Double arg) throws AlgebricksException {
+        return annotate(this, op, arg);
+    }
+
+    @Override
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitInsertDeleteUpsertOperator(InsertDeleteUpsertOperator op,
+            Double arg) throws AlgebricksException {
+        return annotate(this, op, arg);
+    }
+
+    @Override
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitIndexInsertDeleteUpsertOperator(
+            IndexInsertDeleteUpsertOperator op, Double arg) throws 
AlgebricksException {
+        return annotate(this, op, arg);
+    }
+
+    @Override
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitTokenizeOperator(TokenizeOperator op, Double arg)
             throws AlgebricksException {
         return annotate(this, op, arg);
     }

     @Override
-    public Pair<Double, Double> 
visitIndexInsertDeleteUpsertOperator(IndexInsertDeleteUpsertOperator op, Double 
arg)
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitForwardOperator(ForwardOperator op, Double arg)
             throws AlgebricksException {
         return annotate(this, op, arg);
     }

     @Override
-    public Pair<Double, Double> visitTokenizeOperator(TokenizeOperator op, 
Double arg) throws AlgebricksException {
-        return annotate(this, op, arg);
-    }
-
-    @Override
-    public Pair<Double, Double> visitForwardOperator(ForwardOperator op, 
Double arg) throws AlgebricksException {
-        return annotate(this, op, arg);
-    }
-
-    @Override
-    public Pair<Double, Double> visitIntersectOperator(IntersectOperator op, 
Double arg) throws AlgebricksException {
+    public EstimatedCostComputationVisitor.CardSizeCost 
visitIntersectOperator(IntersectOperator op, Double arg)
+            throws AlgebricksException {
         // Needs more work.
         return annotate(this, op, arg);
     }

-    private static Pair<Double, Double> 
annotate(EstimatedCostComputationVisitor visitor, ILogicalOperator op,
-            Double arg) throws AlgebricksException {
-        if (op.getInputs().isEmpty()) {
-            return new Pair<>(0.0, 0.0);
-        }
-        Pair<Double, Double> cardCost = 
op.getInputs().get(0).getValue().accept(visitor, arg);
+    private void annotateOp(ILogicalOperator op, 
EstimatedCostComputationVisitor.CardSizeCost cardSizeCost) {
         op.getAnnotations().put(OperatorAnnotations.OP_OUTPUT_CARDINALITY,
-                (double) Math.round(cardCost.getFirst() * 100) / 100);
+                (double) Math.round(cardSizeCost.getCard() * 100) / 100);
+        op.getAnnotations().put(OperatorAnnotations.OP_OUTPUT_DOCSIZE,
+                (double) Math.round(cardSizeCost.getSize() * 100) / 100);
         op.getAnnotations().put(OperatorAnnotations.OP_COST_TOTAL,
-                (double) Math.round(cardCost.getSecond() * 100) / 100);
+                (double) Math.round(cardSizeCost.getCost() * 100) / 100);
         op.getAnnotations().put(OperatorAnnotations.OP_COST_LOCAL, 0.0);
-        return cardCost;
+    }
+
+    private EstimatedCostComputationVisitor.CardSizeCost 
annotate(EstimatedCostComputationVisitor visitor,
+            ILogicalOperator op, Double arg) throws AlgebricksException {
+        if (op.getInputs().isEmpty()) {
+            return new EstimatedCostComputationVisitor.CardSizeCost(0.0, 0.0, 
0.0);
+        }
+        EstimatedCostComputationVisitor.CardSizeCost cardSizeCost =
+                op.getInputs().getFirst().getValue().accept(visitor, arg);
+        annotateOp(op, cardSizeCost);
+
+        return cardSizeCost;
     }

     // Visits an operator that has the left outer semantics, e.g.,
     // left outer join, left outer unnest, left outer unnest map.
-    private Pair<Double, Double> visitLeftOuterUnnest(ILogicalOperator 
operator, Double arg)
+    private EstimatedCostComputationVisitor.CardSizeCost 
visitLeftOuterUnnest(ILogicalOperator operator, Double arg)
             throws AlgebricksException {
         // Needs more work.
-        return operator.getInputs().get(0).getValue().accept(this, arg);
+        return operator.getInputs().getFirst().getValue().accept(this, arg);
     }

     // Visits an inner join operator.
-    private Pair<Double, Double> visitInnerJoin(InnerJoinOperator 
joinOperator, Double arg) throws AlgebricksException {
-        Pair<Double, Double> cardCost = new Pair<>(0.0, 0.0);
+    private EstimatedCostComputationVisitor.CardSizeCost 
visitInnerJoin(InnerJoinOperator joinOperator, Double arg)
+            throws AlgebricksException {
+        EstimatedCostComputationVisitor.CardSizeCost cardSizeCost =
+                new EstimatedCostComputationVisitor.CardSizeCost(0.0, 0.0, 
0.0);

-        ILogicalOperator left = joinOperator.getInputs().get(0).getValue();
+        ILogicalOperator left = joinOperator.getInputs().getFirst().getValue();
         ILogicalOperator right = joinOperator.getInputs().get(1).getValue();
         double leftExchangeCost = 0;
         double rightExchangeCost = 0;

         for (Map.Entry<String, Object> anno : 
joinOperator.getAnnotations().entrySet()) {
             if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_OUTPUT_CARDINALITY)) {
-                cardCost.setFirst((Double) anno.getValue());
+                cardSizeCost.setCard((Double) anno.getValue());
+            } else if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_OUTPUT_DOCSIZE)) {
+                cardSizeCost.setSize((Double) anno.getValue());
             } else if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_COST_TOTAL)) {
-                cardCost.setSecond((Double) anno.getValue());
+                cardSizeCost.setCost((Double) anno.getValue());
             } else if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_LEFT_EXCHANGE_COST)) {
                 leftExchangeCost = (double) anno.getValue();
             } else if (anno.getValue() != null && 
anno.getKey().equals(OperatorAnnotations.OP_RIGHT_EXCHANGE_COST)) {
@@ -401,6 +457,43 @@
         left.accept(this, leftExchangeCost);
         right.accept(this, rightExchangeCost);

-        return cardCost;
+        return cardSizeCost;
+    }
+
+    public static class CardSizeCost {
+
+        public double card;
+        public double size;
+        public double cost;
+
+        public CardSizeCost(double card, double size, double cost) {
+            this.card = card;
+            this.size = size;
+            this.cost = cost;
+        }
+
+        public double getCard() {
+            return card;
+        }
+
+        public double getSize() {
+            return size;
+        }
+
+        public double getCost() {
+            return cost;
+        }
+
+        public void setCard(double card) {
+            this.card = card;
+        }
+
+        public void setSize(double size) {
+            this.size = size;
+        }
+
+        public void setCost(double cost) {
+            this.cost = cost;
+        }
     }
 }
\ No newline at end of file
diff --git 
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/OperatorAnnotations.java
 
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/OperatorAnnotations.java
index ac038d2..2271272 100644
--- 
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/OperatorAnnotations.java
+++ 
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/OperatorAnnotations.java
@@ -31,6 +31,8 @@
     // Integer
     String OP_INPUT_CARDINALITY = "INPUT_CARDINALITY";
     String OP_OUTPUT_CARDINALITY = "OUTPUT_CARDINALITY";
+    String OP_INPUT_DOCSIZE = "INPUT_DOCSIZE";
+    String OP_OUTPUT_DOCSIZE = "OUTPUT_DOCSIZE";
     String OP_COST_TOTAL = "TOTAL_COST";
     String OP_COST_LOCAL = "OP_COST";
     String OP_LEFT_EXCHANGE_COST = "LEFT_EXCHANGE_COST";
diff --git 
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/AbstractLogicalOperatorPrettyPrintVisitor.java
 
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/AbstractLogicalOperatorPrettyPrintVisitor.java
index 8a08161..fde4a08 100644
--- 
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/AbstractLogicalOperatorPrettyPrintVisitor.java
+++ 
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/AbstractLogicalOperatorPrettyPrintVisitor.java
@@ -36,6 +36,7 @@
 public abstract class AbstractLogicalOperatorPrettyPrintVisitor<T> implements 
ILogicalOperatorVisitor<Void, T> {

     protected static final String CARDINALITY = "cardinality";
+    protected static final String DOCSIZE = "doc-size";
     protected static final String OP_COST_LOCAL = "op-cost";
     protected static final String OP_COST_TOTAL = "total-cost";
     protected final ILogicalExpressionVisitor<String, T> exprVisitor;
@@ -89,6 +90,11 @@
         return (opCard != null) ? opCard : 0.0;
     }

+    protected double getOpDocSize(ILogicalOperator op) {
+        Double opDocSize = (Double) getAnnotationValue(op, 
OperatorAnnotations.OP_OUTPUT_DOCSIZE);
+        return (opDocSize != null) ? opDocSize : 0.0;
+    }
+
     protected double getOpLocalCost(ILogicalOperator op) {
         Double opLocalCost = (Double) getAnnotationValue(op, 
OperatorAnnotations.OP_COST_LOCAL);
         return (opLocalCost != null) ? opLocalCost : 0.0;
diff --git 
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitor.java
 
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitor.java
index f904c56..caf4774 100644
--- 
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitor.java
+++ 
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitor.java
@@ -131,11 +131,12 @@

     private void printOperatorImpl(AbstractLogicalOperator op, int indent, 
boolean printInputs,
             boolean printOptimizerEstimates) throws AlgebricksException {
-        double opCard, opLocalCost, opTotalCost;
+        double opCard, opDocSize, opLocalCost, opTotalCost;

         op.accept(this, indent);
         if (printOptimizerEstimates) {
             opCard = getOpCardinality(op);
+            opDocSize = getOpDocSize(op);
             opLocalCost = getOpLocalCost(op);
             opTotalCost = getOpTotalCost(op);
             buffer.append(" [");
@@ -143,6 +144,10 @@
             buffer.append(": ");
             buffer.append(Double.toString(opCard));
             buffer.append(", ");
+            buffer.append(DOCSIZE);
+            buffer.append(": ");
+            buffer.append(Double.toString(opDocSize));
+            buffer.append(", ");
             buffer.append(OP_COST_LOCAL);
             buffer.append(": ");
             buffer.append(Double.toString(opLocalCost));
diff --git 
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
 
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
index ee125bf..f358ef5 100644
--- 
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
+++ 
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
@@ -482,14 +482,16 @@

     private void generateCardCostFields(AbstractLogicalOperator op, boolean 
printOptimizerEstimates)
             throws AlgebricksException {
-        double opCard, opLocalCost, opTotalCost;
+        double opCard, opDocSize, opLocalCost, opTotalCost;
         if (printOptimizerEstimates) {
             opCard = getOpCardinality(op);
+            opDocSize = getOpDocSize(op);
             opLocalCost = getOpLocalCost(op);
             opTotalCost = getOpTotalCost(op);
             try {
                 jsonGenerator.writeObjectFieldStart(OPTIMIZER_ESTIMATES);
                 jsonGenerator.writeNumberField(CARDINALITY, opCard);
+                jsonGenerator.writeNumberField(DOCSIZE, opDocSize);
                 jsonGenerator.writeNumberField(OP_COST_LOCAL, opLocalCost);
                 jsonGenerator.writeNumberField(OP_COST_TOTAL, opTotalCost);
                 jsonGenerator.writeEndObject();
diff --git 
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
 
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
index f8fb6c2..9427aa0 100644
--- 
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
+++ 
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
@@ -554,6 +554,8 @@
                     case OperatorAnnotations.OP_COST_TOTAL:
                     case OperatorAnnotations.OP_INPUT_CARDINALITY:
                     case OperatorAnnotations.OP_OUTPUT_CARDINALITY:
+                    case OperatorAnnotations.OP_INPUT_DOCSIZE:
+                    case OperatorAnnotations.OP_OUTPUT_DOCSIZE:
                     case OperatorAnnotations.OP_LEFT_EXCHANGE_COST:
                     case OperatorAnnotations.OP_RIGHT_EXCHANGE_COST:
                         destOp.getAnnotations().put(annotation, annotationVal);

--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19392
To unsubscribe, or for help writing mail filters, visit 
https://asterix-gerrit.ics.uci.edu/settings

Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Change-Id: I6a3e8ec8b904b34b96a055b19cd5e826246bd7a0
Gerrit-Change-Number: 19392
Gerrit-PatchSet: 1
Gerrit-Owner: Vijay Sarathy <[email protected]>
Gerrit-MessageType: newchange

Reply via email to