/** * Create and register an {@link Activator} for the {@code operator}. * * @return the newly created {@link Activator} */ protected Activator createActivator(Operator operator) { final Activator pusherActivator = new Activator(operator, this.configuration); this.createdActivators.put(operator, pusherActivator); return pusherActivator; }
public void fire(Queue<Activator> activatorQueue) { assert !this.activator.isActivated[this.inputIndex] : String.format("%s is already activated at input %d.", this.activator.operator, this.inputIndex); this.activator.isActivated[this.inputIndex] = true; if (this.activator.canBeActivated()) { activatorQueue.add(this.activator); } } }
/** * Connect the {@code activator} with already existing {@link Activator}s that are fed by the {@code outputSlot} * via a new {@link Activation}. */ protected void registerDependentActivations(OutputSlot<?> outputSlot, Activator activator) { for (InputSlot<?> inputSlot : outputSlot.getOccupiedSlots()) { Arrays.stream(inputSlot.getOwner().getAllOutputs()) .map(this::getCachedActivator) .filter(Objects::nonNull) .map(dependentActivator -> dependentActivator.createActivation(inputSlot.getIndex())) .forEach(activator.getDependentActivations(outputSlot)::add); } }
final Activator activator = this.createdActivators.get(owner); if (activator != null) { requiredActivations.add(activator.createActivation(inputSlot.getIndex()));
/** * Traverse and update {@link CardinalityEstimate}s. * * @param optimizationContext provides input {@link CardinalityEstimate}s and stores all produces * {@link CardinalityEstimate}s alongside the push traversal * @param configuration provides the applicable {@link Configuration} * @return whether any {@link CardinalityEstimate}s have been updated */ public boolean traverse(OptimizationContext optimizationContext, Configuration configuration) { boolean isUpdated = false; try { final Queue<Activator> activators = this.initializeActivatorQueue(); do { assert !activators.isEmpty() : String.format("No source activators. (input activations: %s)", this.inputActivations); final Activator activator = activators.poll(); isUpdated |= activator.process(optimizationContext, configuration, activators); } while (!activators.isEmpty()); } finally { this.reset(); } return isUpdated; }
/** * Execute this instance, thereby activating new instances and putting them on the queue. * * @param optimizationContext the current {@link OptimizationContext} in which the push should take place * @param activatorQueue accepts newly activated {@link CardinalityEstimator}s */ boolean process(OptimizationContext optimizationContext, Configuration configuration, Queue<Activator> activatorQueue) { OptimizationContext.OperatorContext opCtx = optimizationContext.getOperatorContext(this.operator); assert opCtx != null : String.format("Could not find OperatorContext for %s.", this.operator); // Do the local estimation. boolean isUpdated = this.pusher.push(opCtx, configuration); opCtx.pushCardinalitiesForward(); for (int outputIndex = 0; outputIndex < this.operator.getNumOutputs(); outputIndex++) { // Trigger follow-up operators. this.processDependentActivations(this.dependentActivations[outputIndex], activatorQueue); } return isUpdated; }
/** * Connect the {@code activator} with already existing {@link Activator}s that are fed by the {@code outputSlot} * via a new {@link Activation}. */ protected void registerAsDependentActivation(Activator activator) { for (InputSlot<?> inputSlot : activator.operator.getAllInputs()) { final OutputSlot<?> occupant = inputSlot.getOccupant(); if (Objects.isNull(occupant)) { continue; } final Activator requiredActivator = this.getCachedActivator(occupant); if (requiredActivator == null) { continue; } requiredActivator.getDependentActivations(occupant).add(activator.createActivation(inputSlot.getIndex())); } } }