use of com.alibaba.maxgraph.compiler.tree.VertexTreeNode in project GraphScope by alibaba.
the class NodeLabelList method buildNodeLabel.
/**
* Build label list of current node from parent node, tree node and schema
*
* @param parentNodeLabel The given parent node
* @param treeNode The given tree node
* @param graphSchema The given graph schema
* @return The result node label list
*/
public static NodeLabelList buildNodeLabel(NodeLabelList parentNodeLabel, TreeNode treeNode, GraphSchema graphSchema) {
NodeLabelList nodeLabelList = new NodeLabelList();
if (null == parentNodeLabel) {
BaseTreeNode baseTreeNode = (BaseTreeNode) treeNode;
final Set<String> labelList = Sets.newHashSet();
baseTreeNode.getHasContainerList().forEach(v -> {
if (StringUtils.equals(v.getKey(), T.label.getAccessor())) {
if (v.getBiPredicate() instanceof Compare && v.getBiPredicate() == Compare.eq) {
labelList.add(v.getValue().toString());
} else if (v.getBiPredicate() instanceof Contains && v.getBiPredicate() == Contains.within) {
List<String> labelValueList = (List<String>) v.getValue();
labelList.addAll(labelValueList);
} else {
throw new IllegalArgumentException("Not support label compare " + v.toString());
}
}
});
if (treeNode instanceof SourceVertexTreeNode) {
List<String> vertexLabelList = graphSchema.getVertexList().stream().map(GraphElement::getLabel).collect(Collectors.toList());
Set<String> resultLabelList;
if (labelList.isEmpty()) {
resultLabelList = Sets.newHashSet(vertexLabelList);
} else {
resultLabelList = labelList.stream().filter(vertexLabelList::contains).collect(Collectors.toSet());
}
nodeLabelList.addVertexLabel(resultLabelList);
} else if (treeNode instanceof SourceEdgeTreeNode) {
List<String> edgeLabelList = graphSchema.getEdgeList().stream().map(GraphElement::getLabel).collect(Collectors.toList());
Set<String> resultLabelList;
if (labelList.isEmpty()) {
resultLabelList = Sets.newHashSet(edgeLabelList);
} else {
resultLabelList = labelList.stream().filter(edgeLabelList::contains).collect(Collectors.toSet());
}
nodeLabelList.addEdgeLabel(resultLabelList);
} else {
nodeLabelList.enableUnknown();
}
} else {
Set<String> parentVertexLabelList = Sets.newHashSet();
Set<String> parentEdgeLabelList = Sets.newHashSet();
if (parentNodeLabel.isUnknownFlag()) {
parentVertexLabelList.addAll(graphSchema.getVertexList().stream().map(GraphElement::getLabel).collect(Collectors.toList()));
parentEdgeLabelList.addAll(graphSchema.getEdgeList().stream().map(GraphElement::getLabel).collect(Collectors.toList()));
} else {
parentVertexLabelList.addAll(parentNodeLabel.getVertexLabelList());
parentEdgeLabelList.addAll(parentNodeLabel.getEdgeLabelList());
}
if (treeNode instanceof VertexTreeNode) {
VertexTreeNode vertexTreeNode = (VertexTreeNode) treeNode;
Direction direction = vertexTreeNode.getDirection();
nodeLabelList.addVertexLabel(computeVertexLabelList(parentVertexLabelList, direction, vertexTreeNode.getEdgeLabels(), graphSchema));
} else if (treeNode instanceof EdgeTreeNode) {
EdgeTreeNode edgeTreeNode = (EdgeTreeNode) treeNode;
Direction direction = edgeTreeNode.getDirection();
nodeLabelList.addEdgeLabel(computeEdgeLabelList(parentVertexLabelList, direction, edgeTreeNode.getEdgeLabels(), graphSchema));
} else if (treeNode instanceof EdgeVertexTreeNode) {
EdgeVertexTreeNode edgeVertexTreeNode = (EdgeVertexTreeNode) treeNode;
Map<String, Pair<Set<String>, Set<String>>> edgeSourceTargetPairList = getEdgeSourceTargetPairList(parentEdgeLabelList.toArray(new String[0]), graphSchema);
Direction direction = edgeVertexTreeNode.getDirection();
edgeSourceTargetPairList.forEach((key, value) -> {
switch(direction) {
case OUT:
{
nodeLabelList.addVertexLabel(value.getLeft());
break;
}
case IN:
{
nodeLabelList.addVertexLabel(value.getRight());
break;
}
case BOTH:
{
nodeLabelList.addVertexLabel(value.getLeft());
nodeLabelList.addVertexLabel(value.getRight());
break;
}
}
});
} else if (treeNode instanceof EdgeOtherVertexTreeNode) {
Map<String, Pair<Set<String>, Set<String>>> edgeSourceTargetPairList = getEdgeSourceTargetPairList(parentEdgeLabelList.toArray(new String[0]), graphSchema);
edgeSourceTargetPairList.forEach((key, value) -> {
nodeLabelList.addVertexLabel(value.getLeft());
nodeLabelList.addVertexLabel(value.getRight());
});
} else {
nodeLabelList.enableUnknown();
}
}
return nodeLabelList;
}
use of com.alibaba.maxgraph.compiler.tree.VertexTreeNode in project GraphScope by alibaba.
the class TreeNodeUtils method optimizeSubFilterNode.
/**
* Optimize filter node in TraversalFilterNode
*
* @param filterTreeNode The given filter node
* @return The optimized filter node
*/
public static TreeNode optimizeSubFilterNode(TreeNode filterTreeNode) {
TreeNode sourceNode = getSourceTreeNode(filterTreeNode);
UnaryTreeNode firstNode = (UnaryTreeNode) sourceNode.getOutputNode();
if (firstNode instanceof VertexTreeNode) {
VertexTreeNode vertexTreeNode = (VertexTreeNode) firstNode;
Direction direction = vertexTreeNode.getDirection();
if (direction == Direction.OUT) {
while (true) {
boolean optimizeFinish = true;
TreeNode outputNode = vertexTreeNode.getOutputNode();
if (null == outputNode) {
vertexTreeNode.enableCountFlag();
TreeNode hasTreeNode = new HasTreeNode(vertexTreeNode, Lists.newArrayList(new HasContainer("", P.gt(0L))), vertexTreeNode.getSchema());
hasTreeNode.setOutputNode(null);
break;
}
if (outputNode instanceof RangeGlobalTreeNode) {
TreeNode rangeOutputNode = outputNode.getOutputNode();
vertexTreeNode.setOutputNode(rangeOutputNode);
if (null != rangeOutputNode) {
((UnaryTreeNode) rangeOutputNode).setInputNode(vertexTreeNode);
}
optimizeFinish = false;
} else if (outputNode instanceof CountGlobalTreeNode) {
vertexTreeNode.enableCountFlag();
TreeNode rangeOutputNode = outputNode.getOutputNode();
vertexTreeNode.setOutputNode(rangeOutputNode);
if (null != rangeOutputNode) {
((UnaryTreeNode) rangeOutputNode).setInputNode(vertexTreeNode);
}
optimizeFinish = false;
}
if (optimizeFinish) {
break;
}
}
}
}
TreeNode currentFilterNode = sourceNode;
while (currentFilterNode.getOutputNode() != null) {
currentFilterNode = currentFilterNode.getOutputNode();
}
return currentFilterNode;
}
use of com.alibaba.maxgraph.compiler.tree.VertexTreeNode in project GraphScope by alibaba.
the class CostDataStatistics method computeStepCount.
/**
* Compute step count with given node and node label
*
* @param inputStatistics The given input statistics
* @param treeNode The given tree node
* @param currNodeLabel The given current node label
* @return The result step count
*/
private NodeStatistics computeStepCount(NodeStatistics inputStatistics, TreeNode treeNode, NodeLabelList currNodeLabel) {
GraphSchema schema = schemaFetcher.getSchemaSnapshotPair().getLeft();
NodeStatistics nodeStatistics = new NodeStatistics(schema);
if (null == inputStatistics) {
if (currNodeLabel.isUnknownFlag()) {
for (Map.Entry<String, Double> entry : vertexCountList.entrySet()) {
nodeStatistics.addVertexCount(entry.getKey(), entry.getValue());
}
} else {
SourceTreeNode sourceTreeNode = (SourceTreeNode) treeNode;
Object[] ids = sourceTreeNode.getIds();
Set<String> vertexLabelList = currNodeLabel.getVertexLabelList();
for (String vertexLabel : vertexLabelList) {
double vertexCount = null == ids ? vertexCountList.getOrDefault(vertexLabel, INIT_VERTEX_COUNT) : (ids.length * 1.0 / vertexLabelList.size());
nodeStatistics.addVertexCount(vertexLabel, vertexCount);
}
Set<String> edgeLabelList = currNodeLabel.getEdgeLabelList();
for (String edgeLabel : currNodeLabel.getEdgeLabelList()) {
double edgeCount = null == ids ? edgeCountList.getOrDefault(edgeLabel, INIT_EDGE_COUNT) : (ids.length * 1.0 / edgeLabelList.size());
nodeStatistics.addEdgeCount(edgeLabel, edgeCount);
}
}
} else {
if (treeNode instanceof VertexTreeNode) {
VertexTreeNode vertexTreeNode = (VertexTreeNode) treeNode;
Direction direction = vertexTreeNode.getDirection();
Set<String> edgeLabelList;
if (null == vertexTreeNode.getEdgeLabels()) {
edgeLabelList = Sets.newHashSet();
} else {
edgeLabelList = Sets.newHashSet(vertexTreeNode.getEdgeLabels());
}
switch(direction) {
case OUT:
{
nodeStatistics.merge(getOutRatio(inputStatistics, edgeLabelList));
break;
}
case IN:
{
nodeStatistics.merge(getInRatio(inputStatistics, edgeLabelList));
break;
}
case BOTH:
{
nodeStatistics.merge(getOutRatio(inputStatistics, edgeLabelList));
nodeStatistics.merge(getInRatio(inputStatistics, edgeLabelList));
break;
}
}
} else if (treeNode instanceof EdgeTreeNode) {
Set<String> edgeLabelList = currNodeLabel.getEdgeLabelList();
Direction direction = ((EdgeTreeNode) treeNode).getDirection();
switch(direction) {
case OUT:
{
nodeStatistics.merge(getOutERatio(inputStatistics, edgeLabelList));
break;
}
case IN:
{
nodeStatistics.merge(getInERatio(inputStatistics, edgeLabelList));
break;
}
case BOTH:
{
nodeStatistics.merge(getOutERatio(inputStatistics, edgeLabelList));
nodeStatistics.merge(getInERatio(inputStatistics, edgeLabelList));
break;
}
}
} else if (treeNode instanceof EdgeVertexTreeNode) {
Map<String, Double> edgeCountList = inputStatistics.getEdgeCountList();
Direction direction = ((EdgeVertexTreeNode) treeNode).getDirection();
edgeCountList.keySet().stream().map(v -> {
try {
return schema.getElement(v);
} catch (Exception ignored) {
return null;
}
}).filter(v -> null != v && v instanceof GraphEdge).map(v -> (GraphEdge) v).forEach(v -> {
v.getRelationList().forEach(vv -> {
double currEdgeCount = edgeCountList.get(v.getLabel());
if (direction == Direction.OUT || direction == Direction.BOTH) {
List<String> resultVertexLabelList = Lists.newArrayList();
if (currNodeLabel.getVertexLabelList().contains(vv.getSource().getLabel())) {
resultVertexLabelList.add(vv.getSource().getLabel());
}
double avgVertexCount = currEdgeCount / resultVertexLabelList.size();
for (String vertexLabel : resultVertexLabelList) {
nodeStatistics.addVertexCount(vertexLabel, avgVertexCount);
}
}
if (direction == Direction.IN || direction == Direction.BOTH) {
List<String> resultVertexLabelList = Lists.newArrayList();
if (currNodeLabel.getVertexLabelList().contains(vv.getTarget().getLabel())) {
resultVertexLabelList.add(vv.getTarget().getLabel());
}
double avgVertexCount = currEdgeCount / resultVertexLabelList.size();
for (String vertexLabel : resultVertexLabelList) {
nodeStatistics.addVertexCount(vertexLabel, avgVertexCount);
}
}
});
});
} else if (treeNode instanceof EdgeOtherVertexTreeNode) {
Set<String> vertexLabelList = currNodeLabel.getVertexLabelList();
double avgVertexCount = inputStatistics.totalCount() / vertexLabelList.size();
vertexLabelList.forEach(v -> nodeStatistics.addVertexCount(v, avgVertexCount));
} else {
NodeType nodeType = treeNode.getNodeType();
if (NodeType.MAP == nodeType) {
nodeStatistics.addElementCount(inputStatistics.totalCount());
} else if (NodeType.FILTER == nodeType) {
nodeStatistics.merge(inputStatistics, FILTER_RATIO);
} else if (NodeType.FLATMAP == nodeType) {
nodeStatistics.addElementCount(inputStatistics.totalCount() * FLATMAP_RATIO);
} else if (NodeType.AGGREGATE == nodeType) {
nodeStatistics.addElementCount(1);
} else {
nodeStatistics.merge(inputStatistics);
}
}
}
return nodeStatistics;
}
Aggregations