/** * Moves the operators from this process to another process, keeping all connections intact. TODO: * Test more rigorously. Do we register/unregister everything correctly? * * @return the number of ports the connections of which could not be restored */ public int stealOperatorsFrom(ExecutionUnit otherUnit) { int failedReconnects = 0; // remember source and sink connections so we can reconnect them later. Map<String, InputPort> sourceMap = new HashMap<String, InputPort>(); Map<String, OutputPort> sinkMap = new HashMap<String, OutputPort>(); for (OutputPort source : otherUnit.getInnerSources().getAllPorts()) { if (source.isConnected()) { sourceMap.put(source.getName(), source.getDestination()); } } otherUnit.getInnerSources().disconnectAll(); for (InputPort sink : otherUnit.getInnerSinks().getAllPorts()) { if (sink.isConnected()) { sinkMap.put(sink.getName(), sink.getSource()); } } otherUnit.getInnerSinks().disconnectAll(); // Move operators Iterator<Operator> i = otherUnit.operators.iterator(); while (i.hasNext()) { Operator operator = i.next(); i.remove(); otherUnit.unregister(operator); Process otherProcess = operator.getProcess(); if (otherProcess != null) { operator.unregisterOperator(otherProcess); } this.operators.add(operator); operator.setEnclosingProcess(null); // operator.unregisterOperator(operator.getProcess()); registerOperator(operator, true); // operator.registerOperator(this.getEnclosingOperator().getProcess()); } // Rewire sources and sinks for (Map.Entry<String, InputPort> entry : sourceMap.entrySet()) { OutputPort mySource = getInnerSources().getPortByName(entry.getKey()); if (mySource != null) { mySource.connectTo(entry.getValue()); } else { failedReconnects++; } } getInnerSources().unlockPortExtenders(); for (Map.Entry<String, OutputPort> entry : sinkMap.entrySet()) { InputPort mySink = getInnerSinks().getPortByName(entry.getKey()); if (mySink != null) { entry.getValue().connectTo(mySink); } else { failedReconnects++; } } getInnerSinks().unlockPortExtenders(); fireUpdate(this); return failedReconnects; }
/** * Clones operators contained in <code>original</code>, adds them to this execution unit and wires * them as they were originally. * * @param forParallelExecution Indicates whether this clone is supposed to be executed in * parallel. If yes, the clone will not be registered with the parent process and will share * its {@link Operator#applyCount} with the original. */ public void cloneExecutionUnitFrom(ExecutionUnit original, boolean forParallelExecution) { // Clone operators Map<String, Operator> clonedOperatorsByName = new HashMap<String, Operator>(); for (Operator originalChild : original.operators) { Operator clonedOperator = originalChild.cloneOperator(originalChild.getName(), forParallelExecution); addOperator(clonedOperator, !forParallelExecution); clonedOperatorsByName.put(originalChild.getName(), clonedOperator); } // Restore connections cloneConnections(original.getInnerSources(), original, clonedOperatorsByName); for (Operator op : original.operators) { cloneConnections(op.getOutputPorts(), original, clonedOperatorsByName); } // Unlock original.getInnerSources().unlockPortExtenders(); original.getInnerSinks().unlockPortExtenders(); for (Operator op : this.operators) { op.getInputPorts().unlockPortExtenders(); op.getOutputPorts().unlockPortExtenders(); } // Other: this.expanded = original.expanded; }