// Methods for creating individual vertices
// ------------------------------------------------------------------------
private AbstractJobVertex createSingleInputVertex(SingleInputPlanNode node) throws CompilerException {
final String taskName = node.getNodeName();
final DriverStrategy ds = node.getDriverStrategy();
// check, whether chaining is possible
boolean chaining = false;
{
Channel inConn = node.getInput();
PlanNode pred = inConn.getSource();
chaining = ds.getPushChainDriverClass() != null &&
!(pred instanceof NAryUnionPlanNode) && // first op after union is stand-alone, because union is merged
!(pred instanceof BulkPartialSolutionPlanNode) && // partial solution merges anyways
!(pred instanceof WorksetPlanNode) && // workset merges anyways
!(pred instanceof IterationPlanNode) && // cannot chain with iteration heads currently
inConn.getShipStrategy() == ShipStrategyType.FORWARD &&
inConn.getLocalStrategy() == LocalStrategy.NONE &&
pred.getOutgoingChannels().size() == 1 &&
node.getDegreeOfParallelism() == pred.getDegreeOfParallelism() &&
node.getBroadcastInputs().isEmpty();
// cannot chain the nodes that produce the next workset or the next solution set, if they are not the
// in a tail
if (this.currentIteration != null && this.currentIteration instanceof WorksetIterationPlanNode &&
node.getOutgoingChannels().size() > 0)
{
WorksetIterationPlanNode wspn = (WorksetIterationPlanNode) this.currentIteration;
if (wspn.getSolutionSetDeltaPlanNode() == pred || wspn.getNextWorkSetPlanNode() == pred) {
chaining = false;
}
}
// cannot chain the nodes that produce the next workset in a bulk iteration if a termination criterion follows
if (this.currentIteration != null && this.currentIteration instanceof BulkIterationPlanNode)
{
BulkIterationPlanNode wspn = (BulkIterationPlanNode) this.currentIteration;
if (node == wspn.getRootOfTerminationCriterion() && wspn.getRootOfStepFunction() == pred){
chaining = false;
}else if(node.getOutgoingChannels().size() > 0 &&(wspn.getRootOfStepFunction() == pred ||
wspn.getRootOfTerminationCriterion() == pred)) {
chaining = false;
}
}
}
final AbstractJobVertex vertex;
final TaskConfig config;
if (chaining) {
vertex = null;
config = new TaskConfig(new Configuration());
this.chainedTasks.put(node, new TaskInChain(ds.getPushChainDriverClass(), config, taskName));
} else {
// create task vertex
vertex = new AbstractJobVertex(taskName);
vertex.setInvokableClass((this.currentIteration != null && node.isOnDynamicPath()) ? IterationIntermediatePactTask.class : RegularPactTask.class);
config = new TaskConfig(vertex.getConfiguration());
config.setDriver(ds.getDriverClass());
}
// set user code
config.setStubWrapper(node.getPactContract().getUserCodeWrapper());
config.setStubParameters(node.getPactContract().getParameters());
// set the driver strategy
config.setDriverStrategy(ds);
for(int i=0;i<ds.getNumRequiredComparators();i++) {
config.setDriverComparator(node.getComparator(i), i);
}
// assign memory, file-handles, etc.
assignDriverResources(node, config);
return vertex;