use of com.alibaba.maxgraph.compiler.logical.function.ProcessorRepeatFunction in project GraphScope by alibaba.
the class QueryFlowBuilder method buildQueryFlow.
private void buildQueryFlow(QueryPlan.Builder queryPlanBuilder, LogicalQueryPlan queryPlan, long snapshot) {
List<LogicalVertex> logicalVertexList = queryPlan.getLogicalVertexList();
Map<Integer, Pair<Integer, Integer>> dfsGraphVertexMapping = Maps.newHashMap();
for (LogicalVertex logicalVertex : logicalVertexList) {
ProcessorFunction processorFunction = logicalVertex.getProcessorFunction();
if (processorFunction instanceof ProcessorRepeatFunction) {
ProcessorRepeatFunction processorRepeatFunction = ProcessorRepeatFunction.class.cast(processorFunction);
QueryFlowBuilder repeatBuilder = new QueryFlowBuilder();
QueryFlow queryFlow = repeatBuilder.buildQueryFlow(processorRepeatFunction.getRepeatPlan(), snapshot).build();
RepeatArgumentProto.Builder repeatArgument = RepeatArgumentProto.newBuilder().setPlan(queryFlow.getQueryPlan()).setLoopLimit((int) processorRepeatFunction.getMaxLoopTimes()).setFeedbackId(processorRepeatFunction.getFeedbackVertex().getId()).setEmitFlag(processorRepeatFunction.isHasEmitFlag());
if (processorRepeatFunction.getLeaveVertex() != null) {
repeatArgument.setLeaveId(processorRepeatFunction.getLeaveVertex().getId());
} else {
repeatArgument.setLeaveId(-1);
}
logger.info("repeat argument => ");
logger.info(TextFormat.printToString(repeatArgument));
OperatorBase.Builder repeatBase = OperatorBase.newBuilder().setId(logicalVertex.getId()).setOperatorType(OperatorType.REPEAT).setArgument(Value.newBuilder().setPayload(repeatArgument.build().toByteString()));
queryPlanBuilder.addUnaryOp(UnaryOperator.newBuilder().setBase(repeatBase).setInputOperatorId(queryPlan.getSourceVertex(logicalVertex).getId()));
queryPlanBuilder.addOperatorIdList(logicalVertex.getId());
} else if (processorFunction instanceof ProcessorChainFunction) {
OperatorBase.Builder baseBuilder = OperatorBase.newBuilder();
baseBuilder.setOperatorType(processorFunction.getOperatorType()).setId(logicalVertex.getId());
if (null != logicalVertex.getEarlyStopArgument()) {
baseBuilder.setEarlyStopArgument(logicalVertex.getEarlyStopArgument().build());
}
ProcessorChainFunction processorChainFunction = ProcessorChainFunction.class.cast(processorFunction);
processorChainFunction.getChainVertexList().forEach(v -> baseBuilder.addChainedFunction(createChainedFunction(v)));
if (logicalVertex instanceof LogicalChainSourceVertex) {
LogicalSourceVertex logicalSourceVertex = ((LogicalChainSourceVertex) logicalVertex).getLogicalSourceVertex();
baseBuilder.setArgument(logicalSourceVertex.getProcessorFunction().getArgumentBuilder()).addAllLogicalCompare(logicalSourceVertex.getProcessorFunction().getLogicalCompareList());
SourceOperator.Builder sourceBuilder = SourceOperator.newBuilder().setBase(baseBuilder);
queryPlanBuilder.setSourceOp(sourceBuilder);
} else {
LogicalChainUnaryVertex logicalUnaryVertex = (LogicalChainUnaryVertex) logicalVertex;
UnaryOperator.Builder unaryOperator = UnaryOperator.newBuilder().setBase(baseBuilder).setInputOperatorId(parseInputOperatorId(queryPlan.getSourceVertex(logicalUnaryVertex).getId(), processorFunction.getOperatorType(), dfsGraphVertexMapping));
LogicalEdge logicalEdge = queryPlan.getLogicalEdge(queryPlan.getSourceVertex(logicalUnaryVertex), logicalUnaryVertex);
unaryOperator.setShuffleType(CompilerUtils.parseShuffleTypeFromEdge(logicalEdge)).setInputStreamIndex(logicalEdge.getStreamIndex());
if (logicalEdge.getShuffleType() == EdgeShuffleType.SHUFFLE_BY_KEY) {
InputEdgeShuffle.Builder shuffleBuilder = InputEdgeShuffle.newBuilder().setShuffleType(InputShuffleType.SHUFFLE_BY_ID_TYPE);
if (logicalEdge.getShufflePropId() != 0) {
shuffleBuilder.setShuffleValue(logicalEdge.getShufflePropId());
}
unaryOperator.setInputShuffle(shuffleBuilder);
}
queryPlanBuilder.addUnaryOp(unaryOperator);
}
queryPlanBuilder.addOperatorIdList(logicalVertex.getId());
} else if (processorFunction instanceof ProcessorLabelValueFunction) {
ProcessorLabelValueFunction processorLabelValueFunction = (ProcessorLabelValueFunction) processorFunction;
LogicalVertex labelValueVertex = processorLabelValueFunction.getLabelValueVertex();
OperatorBase.Builder labelOperatorBuilder = createChainedFunction(labelValueVertex);
int labelId = processorLabelValueFunction.getLabelId();
OperatorBase.Builder baseBuilder = OperatorBase.newBuilder().setOperatorType(processorFunction.getOperatorType()).setId(logicalVertex.getId()).setArgument(Value.newBuilder().setIntValue(labelId).setBoolValue(processorLabelValueFunction.getRequireLabelFlag()).setPayload(labelOperatorBuilder.build().toByteString()));
LogicalVertex inputVertex = queryPlan.getSourceVertex(logicalVertex);
UnaryOperator.Builder unaryOperator = UnaryOperator.newBuilder().setBase(baseBuilder).setInputOperatorId(parseInputOperatorId(inputVertex.getId(), processorFunction.getOperatorType(), dfsGraphVertexMapping));
LogicalEdge logicalEdge = queryPlan.getLogicalEdge(inputVertex, logicalVertex);
unaryOperator.setShuffleType(CompilerUtils.parseShuffleTypeFromEdge(logicalEdge)).setInputStreamIndex(logicalEdge.getStreamIndex());
queryPlanBuilder.addUnaryOp(unaryOperator).addOperatorIdList(logicalVertex.getId());
} else {
if (logicalVertex instanceof LogicalSourceDelegateVertex) {
continue;
}
OperatorBase.Builder baseBuilder = OperatorBase.newBuilder();
baseBuilder.setOperatorType(processorFunction.getOperatorType()).setId(logicalVertex.getId());
if (processorFunction.getArgumentBuilder() != null) {
baseBuilder.setArgument(processorFunction.getArgumentBuilder());
}
processorFunction.getLogicalCompareList().forEach(baseBuilder::addLogicalCompare);
if (processorFunction.getRangeLimit() != null) {
baseBuilder.setRangeLimit(processorFunction.getRangeLimit());
}
baseBuilder.addAllAfterRequirement(logicalVertex.getAfterRequirementList().stream().map(v -> v.build()).collect(Collectors.toList()));
baseBuilder.addAllBeforeRequirement(logicalVertex.getBeforeRequirementList().stream().map(v -> v.build()).collect(Collectors.toList()));
if (logicalVertex instanceof LogicalSourceVertex) {
ProcessorSourceFunction processorSourceFunction = (ProcessorSourceFunction) logicalVertex.getProcessorFunction();
SourceOperator.Builder sourceBuilder = SourceOperator.newBuilder().setBase(baseBuilder);
if (null != processorSourceFunction.getOdpsQueryInput()) {
sourceBuilder.setOdpsInput(processorSourceFunction.getOdpsQueryInput()).setSourceType(SourceType.ODPS);
} else {
sourceBuilder.setSourceType(SourceType.GRAPH);
}
queryPlanBuilder.setSourceOp(sourceBuilder);
} else if (logicalVertex instanceof LogicalUnaryVertex) {
EarlyStopArgument.Builder earlyStopArgument = logicalVertex.getEarlyStopArgument();
if (null != earlyStopArgument && (earlyStopArgument.getGlobalFilterFlag() || earlyStopArgument.getGlobalStopFlag())) {
baseBuilder.setEarlyStopArgument(logicalVertex.getEarlyStopArgument().build());
}
LogicalUnaryVertex logicalUnaryVertex = LogicalUnaryVertex.class.cast(logicalVertex);
UnaryOperator.Builder unaryOperator = UnaryOperator.newBuilder().setBase(baseBuilder).setInputOperatorId(parseInputOperatorId(queryPlan.getSourceVertex(logicalUnaryVertex).getId(), processorFunction.getOperatorType(), dfsGraphVertexMapping));
LogicalEdge logicalEdge = queryPlan.getLogicalEdge(queryPlan.getSourceVertex(logicalUnaryVertex), logicalUnaryVertex);
unaryOperator.setShuffleType(CompilerUtils.parseShuffleTypeFromEdge(logicalEdge)).setInputStreamIndex(logicalEdge.getStreamIndex());
queryPlanBuilder.addUnaryOp(unaryOperator);
if (processorFunction.getOperatorType() == OperatorType.DFS_REPEAT_GRAPH) {
VertexIdManager vertexIdManager = queryPlan.getPlanVertexIdManager();
int cmdLeftId = vertexIdManager.getId();
int dataRightId = vertexIdManager.getId();
dfsGraphVertexMapping.put(baseBuilder.getId(), Pair.of(cmdLeftId, dataRightId));
UnaryOperator.Builder cmdLeftOp = UnaryOperator.newBuilder().setBase(OperatorBase.newBuilder().setOperatorType(OperatorType.DFS_REPEAT_CMD).setId(cmdLeftId)).setInputOperatorId(baseBuilder.getId()).setShuffleType(InputShuffleType.FORWARD_TYPE);
queryPlanBuilder.addUnaryOp(cmdLeftOp);
UnaryOperator.Builder dataRightOp = UnaryOperator.newBuilder().setBase(OperatorBase.newBuilder().setOperatorType(OperatorType.DFS_REPEAT_DATA).setId(dataRightId)).setInputOperatorId(baseBuilder.getId()).setShuffleType(InputShuffleType.FORWARD_TYPE);
queryPlanBuilder.addUnaryOp(dataRightOp);
}
} else if (logicalVertex instanceof LogicalBinaryVertex) {
LogicalBinaryVertex logicalBinaryVertex = LogicalBinaryVertex.class.cast(logicalVertex);
BinaryOperator.Builder binaryOperator = BinaryOperator.newBuilder().setBase(baseBuilder).setLeftInputOperatorId(parseInputOperatorId(logicalBinaryVertex.getLeftInput().getId(), processorFunction.getOperatorType(), dfsGraphVertexMapping)).setRightInputOperatorId(parseInputOperatorId(logicalBinaryVertex.getRightInput().getId(), processorFunction.getOperatorType(), dfsGraphVertexMapping));
LogicalEdge leftEdge = queryPlan.getLogicalEdge(logicalBinaryVertex.getLeftInput(), logicalBinaryVertex);
LogicalEdge rightEdge = queryPlan.getLogicalEdge(logicalBinaryVertex.getRightInput(), logicalBinaryVertex);
binaryOperator.setLeftShuffleType(CompilerUtils.parseShuffleTypeFromEdge(leftEdge)).setLeftStreamIndex(leftEdge.getStreamIndex()).setRightShuffleType(CompilerUtils.parseShuffleTypeFromEdge(rightEdge)).setRightStreamIndex(rightEdge.getStreamIndex());
queryPlanBuilder.addBinaryOp(binaryOperator);
} else {
throw new IllegalArgumentException(logicalVertex.toString());
}
queryPlanBuilder.addOperatorIdList(logicalVertex.getId());
Pair<Integer, Integer> dfsCmdPair = dfsGraphVertexMapping.get(logicalVertex.getId());
if (null != dfsCmdPair) {
queryPlanBuilder.addOperatorIdList(dfsCmdPair.getLeft());
queryPlanBuilder.addOperatorIdList(dfsCmdPair.getRight());
}
}
}
}
use of com.alibaba.maxgraph.compiler.logical.function.ProcessorRepeatFunction in project GraphScope by alibaba.
the class LogicalQueryPlan method optimizeLabelDelete.
private void optimizeLabelDelete(Set<Integer> labelUsedList) {
List<LogicalVertex> logicalVertexList = getLogicalVertexList();
for (int i = logicalVertexList.size() - 1; i >= 0; i--) {
LogicalVertex logicalVertex = logicalVertexList.get(i);
if (logicalVertex instanceof LogicalSourceDelegateVertex) {
continue;
}
if (logicalVertex.getProcessorFunction() instanceof ProcessorRepeatFunction) {
ProcessorRepeatFunction processorRepeatFunction = ProcessorRepeatFunction.class.cast(logicalVertex.getProcessorFunction());
processorRepeatFunction.getRepeatPlan().optimizeLogicalPlan(labelUsedList);
continue;
}
Set<Integer> removeLabelList = Sets.newHashSet();
for (Integer labelId : logicalVertex.getProcessorFunction().getFunctionUsedLabelList()) {
if (!labelUsedList.contains(labelId)) {
removeLabelList.add(labelId);
labelUsedList.add(labelId);
}
}
if (!removeLabelList.isEmpty()) {
QueryFlowOuterClass.RequirementValue.Builder removeRequirementBuilder = null;
for (QueryFlowOuterClass.RequirementValue.Builder reqBuilder : logicalVertex.getAfterRequirementList()) {
if (reqBuilder.getReqType() == QueryFlowOuterClass.RequirementType.LABEL_DEL) {
removeRequirementBuilder = reqBuilder;
break;
}
}
if (null == removeRequirementBuilder) {
removeRequirementBuilder = QueryFlowOuterClass.RequirementValue.newBuilder().setReqType(QueryFlowOuterClass.RequirementType.LABEL_DEL);
logicalVertex.getAfterRequirementList().add(removeRequirementBuilder);
}
removeRequirementBuilder.getReqArgumentBuilder().addAllIntValueList(removeLabelList);
}
Iterator<QueryFlowOuterClass.RequirementValue.Builder> reqValueIterator = logicalVertex.getAfterRequirementList().iterator();
while (reqValueIterator.hasNext()) {
QueryFlowOuterClass.RequirementValue.Builder reqBuilder = reqValueIterator.next();
if (reqBuilder.getReqType() == QueryFlowOuterClass.RequirementType.LABEL_START) {
List<Integer> startLabelList = reqBuilder.getReqArgumentBuilder().getIntValueListList().stream().filter(labelUsedList::contains).collect(Collectors.toList());
if (startLabelList.isEmpty()) {
reqValueIterator.remove();
} else {
reqBuilder.getReqArgumentBuilder().clear();
reqBuilder.getReqArgumentBuilder().addAllIntValueList(startLabelList);
}
break;
}
}
reqValueIterator = logicalVertex.getBeforeRequirementList().iterator();
while (reqValueIterator.hasNext()) {
QueryFlowOuterClass.RequirementValue.Builder reqBuilder = reqValueIterator.next();
if (reqBuilder.getReqType() == QueryFlowOuterClass.RequirementType.LABEL_START) {
List<Integer> startLabelList = reqBuilder.getReqArgumentBuilder().getIntValueListList().stream().filter(labelUsedList::contains).collect(Collectors.toList());
if (startLabelList.isEmpty()) {
reqValueIterator.remove();
} else {
reqBuilder.getReqArgumentBuilder().clear();
reqBuilder.getReqArgumentBuilder().addAllIntValueList(startLabelList);
}
break;
}
}
}
}
use of com.alibaba.maxgraph.compiler.logical.function.ProcessorRepeatFunction in project GraphScope by alibaba.
the class RepeatTreeNode method buildLogicalQueryPlan.
@Override
public LogicalSubQueryPlan buildLogicalQueryPlan(ContextManager contextManager) {
TreeNodeLabelManager labelManager = contextManager.getTreeNodeLabelManager();
VertexIdManager vertexIdManager = contextManager.getVertexIdManager();
LogicalSubQueryPlan logicalSubQueryPlan = new LogicalSubQueryPlan(contextManager);
LogicalVertex delegateSourceVertex = getInputNode().getOutputVertex();
logicalSubQueryPlan.addLogicalVertex(delegateSourceVertex);
List<LogicalVertex> outputVertexList = Lists.newArrayList();
LogicalVertex inputVertex = delegateSourceVertex;
ProcessorRepeatFunction processorRepeatFunction = new ProcessorRepeatFunction();
if (null != untilFirstTreeNode) {
Pair<LogicalVertex, Pair<LogicalVertex, LogicalSubQueryPlan>> untilTable = buildUntilQueryPlan(untilTreeNode, delegateSourceVertex, labelManager, contextManager, vertexIdManager);
outputVertexList.add(untilTable.getLeft());
inputVertex = untilTable.getRight().getLeft();
logicalSubQueryPlan.mergeLogicalQueryPlan(untilTable.getRight().getRight());
}
if (null != emitFirstTreeNode) {
LogicalVertex emitVertex;
if (emitFirstTreeNode instanceof SourceDelegateNode) {
emitVertex = inputVertex;
} else {
emitVertex = buildFilterResultPlan(contextManager, vertexIdManager, labelManager, logicalSubQueryPlan, inputVertex, emitFirstTreeNode);
}
outputVertexList.add(emitVertex);
processorRepeatFunction.enableEmitFlag();
}
checkArgument(null != repeatBodyTreeNode, "repeat body tree node can't be null");
processorRepeatFunction.setMaxLoopTimes(maxLoopTimes);
LogicalVertex repeatVertex = new LogicalUnaryVertex(vertexIdManager.getId(), processorRepeatFunction, false, inputVertex);
logicalSubQueryPlan.addLogicalVertex(repeatVertex);
logicalSubQueryPlan.addLogicalEdge(inputVertex, repeatVertex, new LogicalEdge());
List<LogicalVertex> leaveVertexList = Lists.newArrayList();
LogicalSubQueryPlan repeatBodyPlan = new LogicalSubQueryPlan(contextManager);
LogicalSourceDelegateVertex repeatSourceVertex = new LogicalSourceDelegateVertex(inputVertex);
repeatBodyPlan.addLogicalVertex(repeatSourceVertex);
repeatBodyPlan.mergeLogicalQueryPlan(TreeNodeUtils.buildQueryPlanWithSource(repeatBodyTreeNode, labelManager, contextManager, vertexIdManager, repeatSourceVertex));
LogicalVertex feedbackVertex = repeatBodyPlan.getOutputVertex();
if (null != untilTreeNode) {
Pair<LogicalVertex, Pair<LogicalVertex, LogicalSubQueryPlan>> untilTable = buildUntilQueryPlan(untilTreeNode, feedbackVertex, labelManager, contextManager, vertexIdManager);
feedbackVertex = untilTable.getRight().getLeft();
LogicalVertex untilVertex = untilTable.getLeft();
untilVertex.getAfterRequirementList().add(QueryFlowOuterClass.RequirementValue.newBuilder().setReqType(QueryFlowOuterClass.RequirementType.KEY_DEL));
leaveVertexList.add(untilVertex);
repeatBodyPlan.mergeLogicalQueryPlan(untilTable.getRight().getRight());
}
if (null != emitTreeNode) {
LogicalVertex emitVertex;
if (emitTreeNode instanceof SourceDelegateNode) {
emitVertex = feedbackVertex;
} else {
emitVertex = buildFilterResultPlan(contextManager, vertexIdManager, labelManager, repeatBodyPlan, feedbackVertex, emitTreeNode);
}
if (null != dfsEmitTreeNode) {
repeatBodyPlan.mergeLogicalQueryPlan(TreeNodeUtils.buildQueryPlanWithSource(dfsEmitTreeNode, labelManager, contextManager, vertexIdManager, emitVertex));
emitVertex = repeatBodyPlan.getOutputVertex();
}
leaveVertexList.add(emitVertex);
processorRepeatFunction.enableEmitFlag();
}
if (null != dfsFeedTreeNode) {
dfsFeedTreeNode.setRepeatSourceVertex(repeatBodyPlan.getTargetVertex(repeatSourceVertex));
LogicalSubQueryPlan dfsQueryPlan = TreeNodeUtils.buildQueryPlanWithSource(dfsFeedTreeNode, labelManager, contextManager, vertexIdManager, feedbackVertex);
feedbackVertex = dfsQueryPlan.getOutputVertex();
repeatBodyPlan.mergeLogicalQueryPlan(dfsQueryPlan);
}
processorRepeatFunction.setEnterVertex(repeatBodyPlan.getTargetVertex(repeatSourceVertex));
processorRepeatFunction.setFeedbackVertex(feedbackVertex);
processorRepeatFunction.setRepeatPlan(repeatBodyPlan);
if (!leaveVertexList.isEmpty()) {
if (leaveVertexList.size() == 1) {
processorRepeatFunction.setLeaveVertex(leaveVertexList.get(0));
} else {
LogicalVertex unionLeaveVertex = unionVertexList(vertexIdManager, repeatBodyPlan, leaveVertexList);
processorRepeatFunction.setLeaveVertex(unionLeaveVertex);
}
}
LogicalVertex outputVertex = repeatVertex;
if (!outputVertexList.isEmpty()) {
List<LogicalVertex> outputUnionVertexList = Lists.newArrayList(outputVertexList);
outputUnionVertexList.add(repeatVertex);
outputVertex = unionVertexList(vertexIdManager, logicalSubQueryPlan, outputUnionVertexList);
}
addUsedLabelAndRequirement(outputVertex, labelManager);
setFinishVertex(outputVertex, labelManager);
return logicalSubQueryPlan;
}
Aggregations