use of com.alibaba.maxgraph.compiler.tree.BaseTreeNode 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.BaseTreeNode in project GraphScope by alibaba.
the class LogicalPlanBuilder method buildLabelValuePlan.
private void buildLabelValuePlan(LogicalQueryPlan queryPlan, ContextManager contextManager, GraphSchema schema, LogicalVertex outputVertex, TreeNodeLabelManager treeNodeLabelManager, VertexIdManager vertexIdManager, CostMappingManager costMappingManager, String field, TreeNode currNode) {
// Create field value here
String parentField = costMappingManager.getValueParent(field);
if (!StringUtils.isEmpty(parentField)) {
BaseTreeNode nextNode = (BaseTreeNode) currNode.getOutputNode();
nextNode.removeBeforeLabel(parentField);
// If the field is value field, process it and remove the label requirement in vertex
int labelIndex = treeNodeLabelManager.getLabelIndex(parentField);
TreeNode fieldValueTreeNode = costMappingManager.getComputeTreeByValue(parentField);
if (!(fieldValueTreeNode instanceof SourceTreeNode)) {
for (QueryFlowOuterClass.RequirementValue.Builder reqValue : outputVertex.getAfterRequirementList()) {
if (reqValue.getReqType() == QueryFlowOuterClass.RequirementType.LABEL_START) {
List<Integer> labelIndexList = reqValue.getReqArgumentBuilder().getIntValueListList().stream().filter(v -> v != labelIndex).collect(Collectors.toList());
reqValue.getReqArgumentBuilder().clearIntValueList().addAllIntValueList(labelIndexList);
}
}
TreeNode currentFilterTreeNode = TreeNodeUtils.buildSingleOutputNode(fieldValueTreeNode, schema);
// build filter plan, and use join direct filter vertex to filter left stream
LogicalSubQueryPlan fieldValuePlan = TreeNodeUtils.buildSubQueryPlan(currentFilterTreeNode, outputVertex, contextManager);
List<LogicalVertex> fieldValueVertexList = fieldValuePlan.getLogicalVertexList();
if (fieldValueVertexList.size() == 2) {
LogicalVertex fieldValueVertex = fieldValueVertexList.get(1);
ProcessorLabelValueFunction labelValueFunction = new ProcessorLabelValueFunction(labelIndex, fieldValueVertex);
LogicalVertex labelValueVertex = new LogicalUnaryVertex(vertexIdManager.getId(), labelValueFunction, outputVertex);
queryPlan.addLogicalVertex(labelValueVertex);
queryPlan.addLogicalEdge(outputVertex, labelValueVertex, LogicalEdge.shuffleByKey(labelIndex));
} else {
LogicalVertex fieldValueVertex = fieldValuePlan.getOutputVertex();
fieldValueVertex.getAfterRequirementList().add(QueryFlowOuterClass.RequirementValue.newBuilder().setReqType(QueryFlowOuterClass.RequirementType.LABEL_START).setReqArgument(Message.Value.newBuilder().addIntValueList(labelIndex)));
queryPlan.mergeLogicalQueryPlan(fieldValuePlan);
LogicalVertex outputKeyVertex = new LogicalUnaryVertex(vertexIdManager.getId(), new ProcessorFunction(QueryFlowOuterClass.OperatorType.KEY_MESSAGE), fieldValueVertex);
queryPlan.addLogicalVertex(outputKeyVertex);
queryPlan.addLogicalEdge(fieldValueVertex, outputKeyVertex, LogicalEdge.forwardEdge());
}
}
}
}
use of com.alibaba.maxgraph.compiler.tree.BaseTreeNode in project GraphScope by alibaba.
the class LabelPushDownStrategy method apply.
@Override
public void apply(TreeManager treeManager) {
while (true) {
BaseTreeNode treeNode = (BaseTreeNode) TreeNodeUtils.getSourceTreeNode(treeManager.getTreeLeaf());
boolean labelOptimizeFlag = false;
while (true) {
Map<QueryFlowOuterClass.RequirementType, Object> afterRequirementList = treeNode.getAfterRequirementList();
BaseTreeNode outputNode = (BaseTreeNode) treeNode.getOutputNode();
if (null != outputNode && !(outputNode instanceof RepeatTreeNode) && !(outputNode instanceof UnionTreeNode) && !(outputNode instanceof AndTreeNode) && !(outputNode instanceof WherePredicateTreeNode) && outputNode.getNodeType() != NodeType.AGGREGATE) {
Set<String> labelList = (Set<String>) afterRequirementList.remove(QueryFlowOuterClass.RequirementType.LABEL_START);
if (null != labelList) {
labelOptimizeFlag = true;
outputNode.getBeforeRequirementList().put(QueryFlowOuterClass.RequirementType.LABEL_START, labelList);
}
}
if (outputNode == null) {
break;
}
treeNode = outputNode;
}
if (!labelOptimizeFlag) {
break;
}
}
}
Aggregations