/** * 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; }
public void transformMetaData() { List<Operator> sorted = topologicalSort(); for (Operator op : sorted) { op.transformMetaData(); } if (sorted.size() != operators.size()) { List<Operator> remainder = new LinkedList<Operator>(operators); remainder.removeAll(sorted); for (Operator nodeInCircle : remainder) { for (OutputPort outputPort : nodeInCircle.getOutputPorts().getAllPorts()) { InputPort destination = outputPort.getDestination(); if ((destination != null) && remainder.contains(destination.getPorts().getOwner().getOperator())) { if (destination.getSource() != null) { // (source can be null *during* a disconnect in which case // both the source and the destination fire an update // which leads to this inconsistent state) destination.addError(new OperatorLoopError(destination)); } outputPort.addError(new OperatorLoopError(outputPort)); } } } } getInnerSinks().checkPreconditions(); }
/** * Sorts the operators topologically, i.e. such that operator <var>i</var> in the returned * ordering has dependencies (i.e. connected {@link InputPort}s) only from operators * <var>0..i-1</var>. */ public Vector<Operator> topologicalSort() { final Map<Operator, Integer> originalIndices = new HashMap<Operator, Integer>(); for (int i = 0; i < operators.size(); i++) { originalIndices.put(operators.get(i), i); } EdgeCounter counter = new EdgeCounter(operators); for (Operator child : getOperators()) { for (OutputPort out : child.getOutputPorts().getAllPorts()) { InputPort dest = out.getDestination(); if (dest != null) { counter.incNumEdges(dest.getPorts().getOwner().getOperator()); } } } Vector<Operator> sorted = new Vector<Operator>(); PriorityQueue<Operator> independentOperators = new PriorityQueue<Operator>( Math.max(1, operators.size()), new Comparator<Operator>() { @Override public int compare(Operator o1, Operator o2) { return originalIndices.get(o1) - originalIndices.get(o2); } }); independentOperators.addAll(counter.getIndependentOperators()); while (!independentOperators.isEmpty()) { Operator first = independentOperators.poll(); sorted.add(first); for (OutputPort out : first.getOutputPorts().getAllPorts()) { InputPort dest = out.getDestination(); if (dest != null) { Operator destOp = dest.getPorts().getOwner().getOperator(); if (counter.decNumEdges(destOp) == 0) { // independentOperators.addFirst(destOp); independentOperators.add(destOp); } } } } return sorted; }
private void cloneConnections( OutputPorts originalPorts, ExecutionUnit originalExecutionUnit, Map<String, Operator> clonedOperatorsByName) { for (OutputPort originalSource : originalPorts.getAllPorts()) { if (originalSource.isConnected()) { OutputPort mySource; if (originalPorts.getOwner().getOperator() == originalExecutionUnit.getEnclosingOperator()) { // this is an inner source mySource = getInnerSources().getPortByName(originalSource.getName()); if (mySource == null) { throw new RuntimeException( "Error during clone: Corresponding source for " + originalSource + " not found (no such inner source)."); } } else { // this is an output port Operator myOperator = clonedOperatorsByName.get( originalSource.getPorts().getOwner().getOperator().getName()); if (myOperator == null) { throw new RuntimeException( "Error during clone: Corresponding source for " + originalSource + " not found (no such operator)."); } mySource = myOperator.getOutputPorts().getPortByName(originalSource.getName()); if (mySource == null) { throw new RuntimeException( "Error during clone: Corresponding source for " + originalSource + " not found (no such output port)."); } } InputPort originalDestination = originalSource.getDestination(); InputPort myDestination; if (originalDestination.getPorts().getOwner().getOperator() == originalExecutionUnit.getEnclosingOperator()) { // this is an inner sink myDestination = getInnerSinks().getPortByName(originalDestination.getName()); if (myDestination == null) { throw new RuntimeException( "Error during clone: Corresponding destination for " + originalDestination + " not found (no such inner sink)."); } } else { // this is an input port Operator myOperator = clonedOperatorsByName.get( originalDestination.getPorts().getOwner().getOperator().getName()); if (myOperator == null) { throw new RuntimeException( "Error during clone: Corresponding destination for " + originalDestination + " not found (no such operator)."); } myDestination = myOperator.getInputPorts().getPortByName(originalDestination.getName()); if (myDestination == null) { throw new RuntimeException( "Error during clone: Corresponding destination for " + originalDestination + " not found (no such input port)."); } } mySource.connectTo(myDestination); } } }