/** * Merges this instance into the original instance ({@link #getOriginal()}. * <p>The consumers of the original instance are cleared and replaced with the consumers of this instance. * For all other properties, the original and this instance should agree.</p> */ public void mergeIntoOriginal() { if (!this.isCopy()) return; this.getOriginal().copyConsumersFrom(this); this.getOriginal().adoptSiblings(this); }
/** * Copies the consumers of the given {@code channel} into this instance. */ private void copyConsumersFrom(Channel channel) { assert channel.getOriginal() == this; for (ExecutionTask consumer : new ArrayList<>(channel.getConsumers())) { // We must take care not to copy back channels, that we already have in the original. assert this.consumers.stream() .noneMatch(existingConsumer -> existingConsumer.getOperator().equals(consumer.getOperator())) : String.format("Conflict when copying consumers from %s (%s) to %s (%s).", this, this.consumers, channel, channel.getConsumers() ); consumer.exchangeInputChannel(channel, this); } }
/** * Creates a new, hierarchical instance. Mimes the {@code original}'s properties except for the {@link #consumers}. * * @param original the original instance whose properties will be mimed */ protected Channel(Channel original) { this.descriptor = original.getDescriptor(); this.original = original.getOriginal(); assert this.original == null || !this.original.isCopy(); this.producer = original.getProducer(); this.producerSlot = original.getProducerSlot(); }
/** * The given instance should build upon the open {@link Channel}s of this instance. Then, this instance will be * expanded with the content of the given instance. * * @param expansion extends this instance, but they are not overlapping */ public void expand(ExecutionPlan expansion) { for (Channel openChannel : expansion.getOpenInputChannels()) { openChannel.mergeIntoOriginal(); final Channel original = openChannel.getOriginal(); final ExecutionStage producerStage = original.getProducer().getStage(); assert producerStage != null : String.format("No stage found for %s.", original.getProducer()); for (ExecutionTask consumer : original.getConsumers()) { final ExecutionStage consumerStage = consumer.getStage(); assert consumerStage != null : String.format("No stage found for %s.", consumer); // Equal stages possible on "partially open" Channels. if (producerStage != consumerStage) { producerStage.addSuccessor(consumerStage); } } } }