drill-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sor...@apache.org
Subject [drill] branch master updated: DRILL-6515: Render a link between the Unnest operator and it's source
Date Tue, 26 Jun 2018 20:21:16 GMT
This is an automated email from the ASF dual-hosted git repository.

sorabh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/drill.git


The following commit(s) were added to refs/heads/master by this push:
     new 4b028fe  DRILL-6515: Render a link between the Unnest operator and it's source
4b028fe is described below

commit 4b028fe81ead796e0450036e19d161124b1f8470
Author: Kunal Khatua <kkhatua@users.noreply.github.com>
AuthorDate: Tue Jun 26 13:21:13 2018 -0700

    DRILL-6515: Render a link between the Unnest operator and it's source
    
    * DRILL-6515: Render a link between the Unnest operator and it's source
    
    1. Unnest operator is expected to specify srcOp=##-## to help identify the source of its
input.
    2. Implicit Source Map is leveraged to capture implicit data flow pipelines between Unnest
and Lateral. (Can be expanded to other operators too).
    3. In addition, code refactored for more readability.
    
    * Minor comment updates
    
    * Minor Update
    
    Converted implicitSrc to a local variable
    
    closes #1327
---
 .../src/main/resources/rest/static/js/graph.js     | 80 +++++++++++++++++-----
 1 file changed, 61 insertions(+), 19 deletions(-)

diff --git a/exec/java-exec/src/main/resources/rest/static/js/graph.js b/exec/java-exec/src/main/resources/rest/static/js/graph.js
index 360e9c4..9ea117c 100644
--- a/exec/java-exec/src/main/resources/rest/static/js/graph.js
+++ b/exec/java-exec/src/main/resources/rest/static/js/graph.js
@@ -94,33 +94,75 @@ $(window).on('load',(function () {
 
     // parse the short physical plan into a dagreeD3 structure
     function parseplan (planstring) {
+        //Map for implicit links
+        var implicitSrcMap = {};
         var g = new dagreD3.Digraph();
-        var ps = $.map(planstring.trim().split("\n"), function (s) {
-            return [/^([0-9-]+)( *)([a-zA-Z]*)/.exec(s).slice(1)];
-        });
+        //Produce 2D array (3 x M): [[0:majorMinor] [1:] [2:opName]] / [[<major>-<minor>,
"<indent>", opName]]
+        let opPlanArray = planstring.trim().split("\n");
+        var operatorRegex = new RegExp("^([0-9-]+)( *)([a-zA-Z]*)");
+        //Regex to capture source operator 
+        var srcOpRegex = new RegExp("srcOp=[0-9-]+");
+        var opTuple = $.map(opPlanArray, 
+            function (lineStr) { 
+              //Tokenize via Regex
+              let opToken = operatorRegex.exec(lineStr).slice(1);
+              //Extract Implicit Source via Regex
+              let implicitSrc = srcOpRegex.exec(lineStr);
+              let srcOp = null;
+              let tgtOp = opToken[0];
+              if (implicitSrc != null) {
+                srcOp = implicitSrc.toString().split("=")[1];
+                implicitSrcMap[tgtOp]=srcOp;
+              }
+              return [opToken];
+            });
+
 
-        // nodes
-        for (var i = 0; i < ps.length; i++) {
-            g.addNode(ps[i][0], {
-                label: ps[i][2] + " " + ps[i][0],
-                fragment: parseInt(ps[i][0].split("-")[0])
+        // parse, build & inject nodes
+        for (var i = 0; i < opTuple.length; i++) {
+            let majorMinor = opTuple[i][0];
+            let majorId = parseInt(majorMinor.split("-")[0]);
+            let opName = opTuple[i][2];
+            g.addNode(majorMinor, {
+                label: opName + " " + majorMinor,
+                fragment: majorId
             });
         }
 
-        // edges
-        var st = [ps[0]];
-        for (var i = 1; i < ps.length; i++) {
-            var top = st.pop();
-            while (top[1].length >= ps[i][1].length)
-                top = st.pop();
+        // Define edges by traversing graph from root node (Screen)
+        //NOTE: The indentation value in opTuple which is opTuple[1] represents the relative
level of each operator in tree w.r.t root operator
+        var nodeStack = [opTuple[0]]; //Add Root
+        for (var i = 1; i < opTuple.length; i++) {
+            let top = nodeStack.pop();
+            let currItem = opTuple[i];
+            let stackTopIndent = top[1].length;
+            let currItemIndent = currItem[1].length; //Since tokenizing gives indent size
at index 1
+            //Compare top-of-stack indent with current iterItem indent
+            while (stackTopIndent >= currItemIndent) {
+                top = nodeStack.pop();
+                stackTopIndent = top[1].length;
+            }
 
-            g.addEdge(null, ps[i][0], top[0]);
+            //Found parent
+            //Add edge if Implicit src exists
+            //Refer: https://dagrejs.github.io/project/dagre-d3/latest/demo/style-attrs.html
/ https://github.com/d3/d3-shape#curves
+            if (implicitSrcMap[currItem[0]] != null) {
+                //Note: Order matters because it affects layout (currently: BT)
+                //Ref: //https://github.com/dagrejs/dagre/issues/116
+                g.addEdge(null, currItem[0], implicitSrcMap[currItem[0]], {
+                    style: "fill:none; stroke:gray; stroke-width:3px; stroke-dasharray: 5,5;marker-end:none"
+                });
+                
+            }
+            //Adding edge
+            g.addEdge(null, currItem[0], top[0]);
 
-            if (ps[i][1].length != top[1].length)
-                st.push(top);
-            if (ps[i][1].length >= top[1].length)
-                st.push(ps[i]);
+            if (currItemIndent != stackTopIndent)
+                nodeStack.push(top);
+            if (currItemIndent >= stackTopIndent)
+                nodeStack.push(currItem);
         }
+
         return g;
     }
 


Mime
View raw message