You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by pa...@apache.org on 2017/02/24 14:05:15 UTC

ambari git commit: AMBARI-20168. Hive 2: Compact Visual Explain Plan is not loading in firefox (pallavkul)

Repository: ambari
Updated Branches:
  refs/heads/trunk 1d3dce261 -> da9086dca


AMBARI-20168. Hive 2: Compact Visual Explain Plan is not loading in firefox (pallavkul)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/da9086dc
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/da9086dc
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/da9086dc

Branch: refs/heads/trunk
Commit: da9086dcaaf161a15e58bfc5fe44c338da18078d
Parents: 1d3dce2
Author: pallavkul <pa...@gmail.com>
Authored: Fri Feb 24 19:34:17 2017 +0530
Committer: pallavkul <pa...@gmail.com>
Committed: Fri Feb 24 19:34:17 2017 +0530

----------------------------------------------------------------------
 .../ui/app/templates/queries/query/log.hbs      |   2 +-
 .../ui/app/templates/queries/query/results.hbs  |   2 +-
 .../templates/queries/query/visual-explain.hbs  |   2 +-
 .../ui/app/utils/hive-explainer/processor.js    |  32 +++++-
 .../ui/app/utils/hive-explainer/renderer.js     |  55 ++++++++-
 .../ui/app/utils/hive-explainer/transformer.js  | 115 +++++++++++++------
 6 files changed, 160 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/da9086dc/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/log.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/log.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/log.hbs
index db1cea2..c7e30f2 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/log.hbs
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/log.hbs
@@ -17,7 +17,7 @@
 }}
 
 {{#unless hasJobAssociated}}
-  <div>No Log avaiable.</div>
+  <div>No Log available.</div>
 {{/unless}}
 
 {{#if hasJobAssociated}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/da9086dc/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/results.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/results.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/results.hbs
index 370e3ef..d859b04 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/results.hbs
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/results.hbs
@@ -19,7 +19,7 @@
 {{outlet}}
 
 {{#unless hasJobAssociated}}
-  <div>No Results avaiable.</div>
+  <div>No Results available.</div>
 {{/unless}}
 
 {{#if hasJobAssociated}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/da9086dc/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/visual-explain.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/visual-explain.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/visual-explain.hbs
index ef441b5..5b7e566 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/visual-explain.hbs
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/visual-explain.hbs
@@ -19,7 +19,7 @@
 {{outlet}}
 
 {{#unless hasJobAssociated}}
-  <div>No Visual Explain avaiable.</div>
+  <div>No Visual Explain available.</div>
 {{/unless}}
 
 {{#if hasJobAssociated}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/da9086dc/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/processor.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/processor.js b/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/processor.js
index 5dbeb2b..a252498 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/processor.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/processor.js
@@ -25,11 +25,12 @@ function processEdges(vertices, edges) {
 
   return vertices
     .map(cVertex => {
-      const isVertexPartOfSimpleEdge = edges.some(cEdge => cEdge.type === 'SIMPLE_EDGE' && cEdge.parent === cVertex._vertex);
-      const isVertexPartOfBroadcastEdge = edges.some(cEdge => cEdge.type === 'BROADCAST_EDGE' && cEdge.parent === cVertex._vertex);
-      const isVertexPartOfCustomSimpleEdge = edges.some(cEdge => cEdge.type === 'CUSTOM_SIMPLE_EDGE' && cEdge.parent === cVertex._vertex);
-      const isVertexPartOfCustomEdge = edges.some(cEdge => cEdge.type === 'CUSTOM_EDGE' && cEdge.parent === cVertex._vertex);
-      const isVertexPartOfXProdEdge = edges.some(cEdge => cEdge.type === 'XPROD_EDGE' && cEdge.parent === cVertex._vertex);
+      const isVertexPartOfSimpleEdge = edges.some(cEdge => cEdge.type === 'SIMPLE_EDGE' && cEdge._source === cVertex._vertex);
+      const isVertexPartOfBroadcastEdge = edges.some(cEdge => cEdge.type === 'BROADCAST_EDGE' && cEdge._source === cVertex._vertex);
+      const isVertexPartOfCustomSimpleEdge = edges.some(cEdge => cEdge.type === 'CUSTOM_SIMPLE_EDGE' && cEdge._source === cVertex._vertex);
+      const isVertexPartOfCustomEdge = edges.some(cEdge => cEdge.type === 'CUSTOM_EDGE' && cEdge._source === cVertex._vertex);
+      const isVertexPartOfXProdEdge = edges.some(cEdge => cEdge.type === 'XPROD_EDGE' && cEdge._source === cVertex._vertex);
+      const isVertexPartOfUnionEdge = edges.some(cEdge => cEdge.type === 'CONTAINS' && cEdge._source === cVertex._vertex);
 
       let tVertex = cVertex;
 
@@ -58,6 +59,11 @@ function processEdges(vertices, edges) {
           _operator: 'Cross-product Distribute Pseudo-Edge'
         });
       }
+      if(isVertexPartOfUnionEdge) {
+        tVertex = appendIfTerminusOfOperator(tVertex, {
+          _operator: 'Partition/Sort Pseudo-Edge'
+        });
+      }
 
       return tVertex;
     });
@@ -238,3 +244,19 @@ function doCloneAndOmit(obj, keys) {
       [cObjKey]: obj[cObjKey]
     }), {});
 }
+
+export function getEdgesWithCorrectedUnion(edges) {
+
+  return edges
+      .map(cEdge => {
+        if(cEdge.type === 'CONTAINS') {
+          return Object.assign({}, cEdge, {
+            _source: cEdge._target,
+            _target: cEdge._source,
+          });
+        } else {
+          return cEdge;
+        }
+      });
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/da9086dc/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/renderer.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/renderer.js b/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/renderer.js
index 5fa5d2e..196a514 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/renderer.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/renderer.js
@@ -18,7 +18,7 @@
 
 export default function doRender(data, selector, onRequestDetail) {
 
-  const width = '100vw', height = '100vh';
+  const width = '1200', height = '960';
 
   d3.select(selector).select('*').remove();
   const svg =
@@ -30,7 +30,8 @@ export default function doRender(data, selector, onRequestDetail) {
   const container = svg.append('g');
   const zoom =
     d3.behavior.zoom()
-      .scaleExtent([1 / 10, 4])
+      .scale(1/10)
+      .scaleExtent([1 / 10, 1])
       .on('zoom', () => {
         container.attr('transform', `translate(${d3.event.translate}) scale(${d3.event.scale})`);
       });
@@ -58,7 +59,7 @@ export default function doRender(data, selector, onRequestDetail) {
     .enter()
       .insert('path', ':first-child')
     .attr('class', 'edge')
-    .attr('d', d => getConnectionPath(d, svg, container));
+    .attr('d', d => (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) ? getConnectionPathFF(d, svg, container) : getConnectionPath(d, svg, container));
 
   reset(zoom, svg, container);
 
@@ -273,7 +274,51 @@ function reset(zoom, svg, container) {
     .call( zoom.event );
 }
 
-function getConnectionPath(connector, svg, container) {
+function getConnectionPathFF(connector, svg, container) {
+  const source = container.select(`#${connector._source._uuid}`).node();
+  const target = container.select(`#${connector._target._uuid}`).node();
+  const rSource = d3.select(source).data()[0];
+  const rTarget = d3.select(target).data()[0];
+  const rSourceVertex = d3.select($(source).closest('.vertex').get(0)).data()[0];
+  const rTargetVertex = d3.select($(target).closest('.vertex').get(0)).data()[0];
+
+  const offsetBox = $(container.node()).children('.vertex').get(0).getBoundingClientRect();
+
+
+  const pSource = {
+    x: offsetBox.left - 200 + (rSourceVertex._X + (rSourceVertex._widthOfSelf - (rSource._indexX + 1))) * 200 + 140 / 2,
+    y: offsetBox.top + (rSourceVertex._Y + rSource._indexY) * 100 + 55 / 2,
+  };
+  const pTarget = {
+    x: offsetBox.left - 200 + (rTargetVertex._X + (rTargetVertex._widthOfSelf - (rTarget._indexX + 1))) * 200 + 140 / 2,
+    y: offsetBox.top + (rTargetVertex._Y + rTarget._indexY) * 100 + 55 / 2,
+  };
+  const path = [
+    pTarget
+  ];
+  const junctionXMultiplier = (pTarget.x - pSource.x < 0) ? +1 : -1;
+  if(pSource.y !== pTarget.y) {
+    path.push({
+      x: pTarget.x + junctionXMultiplier * 90,
+      y: pTarget.y
+    }, {
+      x: pTarget.x + junctionXMultiplier * 90,
+      y: pSource.y
+    });
+  }
+  path.push(pSource);
+  const offsetY = svg.node().getBoundingClientRect().top;
+  return path.reduce((accumulator, cPoint, index) => {
+    if(index === 0) {
+      return accumulator + `M ${cPoint.x}, ${cPoint.y - offsetY}\n`
+    } else {
+      return accumulator + `L ${cPoint.x}, ${cPoint.y - offsetY}\n`
+    }
+  }, '');
+}
+
+
+function getConnectionPath(connector, svg, container){
   const operators = container.selectAll('.operator');
   const source = container.select(`#${connector._source._uuid}`);
   const target = container.select(`#${connector._target._uuid}`);
@@ -317,7 +362,7 @@ function doClean(node) {
   } else {
     return (
       Object.keys(node)
-        .filter(cNodeKey => cNodeKey !== '_children' && cNodeKey !== '_uuid')
+        .filter(cNodeKey => cNodeKey === '_operator' || !cNodeKey.startsWith('_'))
         .reduce((accumulator, cNodeKey) => {
           accumulator[cNodeKey] = node[cNodeKey];
           return accumulator;

http://git-wip-us.apache.org/repos/asf/ambari/blob/da9086dc/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/transformer.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/transformer.js b/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/transformer.js
index 70647a8..01d6000 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/transformer.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/utils/hive-explainer/transformer.js
@@ -17,7 +17,7 @@
  */
 
 import doEnhance from './enhancer';
-import {getProcessedVertices} from './processor';
+import {getProcessedVertices, getEdgesWithCorrectedUnion} from './processor';
 
 export default function doTransform(data) {
   const plan = getTezPlan(data);
@@ -29,22 +29,23 @@ export default function doTransform(data) {
   ];
 
   const tezEdges = getEdges(plan, vertices);
-  const edges = getEdgesWithFetch(tezEdges, vertices);
+  const edgesWithCorrectedUnion = getEdgesWithCorrectedUnion(tezEdges);
+  const edges = getEdgesWithFetch(edgesWithCorrectedUnion, vertices);
 
   const enhancedVertices = doEnhance(vertices);
 
   const processedVertices = getProcessedVertices(enhancedVertices, edges);
 
+  const verticesWithIndexOfChildren = getVerticesWithIndexOfChildren(processedVertices);
 
   const tree = getVertexTree(edges);
-  const connections = getConnections(processedVertices, edges);
-  const treeWithOffsetY = getTreeWithOffsetAndHeight(tree, processedVertices, connections);
+  const connections = getConnections(verticesWithIndexOfChildren, edges);
+  const treeWithOffsetY = getTreeWithOffsetAndHeight(tree, verticesWithIndexOfChildren, connections);
 
-
-  const nodes = getNodes(processedVertices);
+  const nodes = getNodes(verticesWithIndexOfChildren);
 
   return ({
-    vertices: processedVertices,
+    vertices: verticesWithIndexOfChildren,
     edges,
     tree: treeWithOffsetY,
     nodes,
@@ -52,6 +53,32 @@ export default function doTransform(data) {
   });
 }
 
+function getVerticesWithIndexOfChildren(vertices) {
+  const verticesWithIndexX = vertices.map(cVertex => Object.assign({}, cVertex, {
+    _children: doGetChildrenWithIndexX(cVertex._children, 0)
+  }));
+
+  const verticesWithIndexY = verticesWithIndexX.map(cVertex => Object.assign({}, cVertex, {
+    _children: doGetChildrenWithIndexY(cVertex._children, 0)
+  }));
+
+  return verticesWithIndexY;
+}
+
+function doGetChildrenWithIndexX(children, cIndex) {
+  return children.map(cChild => Object.assign({}, cChild, {
+    _indexX: cIndex,
+    _children: doGetChildrenWithIndexX(cChild._children, cIndex + 1)
+  }))
+}
+
+function doGetChildrenWithIndexY(children, cIndex) {
+  return children.map((cChild, index) => Object.assign({}, cChild, {
+    _indexY: cIndex + index,
+    _children: doGetChildrenWithIndexY(cChild._children, cIndex + index)
+  }))
+}
+
 function getTezPlan(data) {
   const stages = data['STAGE PLANS'];
   const tezStageKey = Object.keys(stages).find(cStageKey => stages[cStageKey].hasOwnProperty('Tez'));
@@ -179,21 +206,17 @@ function doHarmonize(nodes) {
   });
 }
 
-function doGetHeightOfNodes(children) {
-  if(children.length > 0) {
-    return children.reduce((height, cChild) => height + doGetHeightOfNodes(cChild._children), 0);
-  }
-  return 1;
-}
-
 function getTreeWithOffsetAndHeight(node, vertices, connections) {
-  const treeWithCumulativeHeight = getTreeWithCumulativeHeight(node, vertices);
-  const treeWithCumulativeWidth = getTreeWithIndividualWidth(treeWithCumulativeHeight, vertices);
-  const treeWithOffsetY = Object.assign({}, getTreeWithOffsetYInHiererchy(treeWithCumulativeWidth, connections), {
+  const treeWithCumulativeHeight = getTreeWithCumulativeHeight(node, vertices, connections);
+  const treeWithIndividualWidth = getTreeWithIndividualWidth(treeWithCumulativeHeight, vertices);
+  //const treeWithCumulativeWidth = getTreeWithCumulativeWidth(treeWithIndividualWidth);
+  const treeWithOffsetY = Object.assign({}, getTreeWithOffsetYInHiererchy(treeWithIndividualWidth, connections), {
     _offsetY: 0
   });
+  const treeWithEffectiveOffsetX =  getTreeWithEffectiveOffsetX(treeWithOffsetY, 0);
+  const treeWithEffectiveOffsetY =  getTreeWithEffectiveOffsetY(treeWithEffectiveOffsetX, 0);
 
-  return treeWithOffsetY;
+  return treeWithEffectiveOffsetY;
 }
 
 function doGetWidthOfNodes(children = []) {
@@ -203,15 +226,50 @@ function doGetWidthOfNodes(children = []) {
   return 1 + Math.max(0, ...children.map(cChild => doGetWidthOfNodes(cChild._children)));
 }
 
-function getTreeWithCumulativeHeight(node, vertices) {
+function getTreeWithEffectiveOffsetX(node, positionX) {
+  const _vertices = node._vertices.map(cVertex => getTreeWithEffectiveOffsetX(cVertex, positionX + node._widthOfSelf));
+
+  return Object.assign({}, node, {
+    _X: positionX,
+    _vertices,
+  });
+}
+
+function getTreeWithEffectiveOffsetY(node, positionY) {
+  const _vertices = node._vertices.map(cVertex => getTreeWithEffectiveOffsetY(cVertex, positionY + cVertex._offsetY));
+
+  return Object.assign({}, node, {
+    _Y: positionY,
+    _vertices,
+  });
+}
+
+function doGetHeightOfNodes(children) {
+  if(children.length > 0) {
+    return children.reduce((height, cChild) => height + doGetHeightOfNodes(cChild._children), 0);
+  }
+  return 1;
+}
+
+function getTreeWithCumulativeHeight(node, vertices, connections) {
   const vertexKey = node._vertex;
   const vertex = vertices.find(cVertex => cVertex._vertex === vertexKey);
 
+  // if does not overlap > add 1
+  const vertexNext = node._vertices[0] && vertices.find(cVertex => cVertex._vertex === node._vertices[0]._vertex);
+  const source = vertexNext && getLastOperatorOf(vertexNext);
+  const target = getFirstOperatorOf(vertex);
+  const isFirstConnectedToLast = connections.some(cConnection => source && target && cConnection._source._uuid === source._uuid && cConnection._target._uuid === target._uuid);
+
+
   let _height = doGetHeightOfNodes(vertex._children);
   let _vertices = [];
   if(Array.isArray(node._vertices)){
-    _vertices = node._vertices.map(cVertex => getTreeWithCumulativeHeight(cVertex, vertices));
-    _height = Math.max(_height, _vertices.reduce((height, cVertex) => height + cVertex._height, 1));
+    _vertices = node._vertices.map(cVertex => getTreeWithCumulativeHeight(cVertex, vertices, connections));
+    _height = Math.max(_height, _vertices.reduce((height, cVertex) => height + cVertex._height, 0));
+  }
+  if(source && !isFirstConnectedToLast) {
+    _height = _height + 1;
   }
   return Object.assign({}, node, vertex, {
     _height,
@@ -288,20 +346,7 @@ function getEdges(plan, vertices) {
         }
       }, []);
 
-  const edgesWithFixedUnions =
-    edges
-      .map(cEdge => {
-        if(cEdge.type === 'CONTAINS') {
-          return Object.assign({}, cEdge, {
-            _source: cEdge._target,
-            _target: cEdge._source,
-          });
-        } else {
-          return cEdge;
-        }
-      });
-
-  return edgesWithFixedUnions;
+  return edges;
 }
 
 function doCloneAndOmit(obj, keys) {