/** * Create an instance that pushes {@link CardinalityEstimate}s through a data flow plan starting at the given * {@code inputSlots} and {@code sourceOperators}, thereby putting {@link CardinalityEstimate}s into the * {@code cache}. * * @param inputSlots open {@link InputSlot}s that will be initially activated * @param borderInputSlots that will not be followed; they are terminal in addition to {@link OutputSlot}s that * have no occupied {@link InputSlot}s * @param sourceOperators {@link Operator} that will be initially activated * @param configuration provides utilties for the estimation */ public static CardinalityEstimationTraversal createPushTraversal(Collection<InputSlot<?>> inputSlots, Collection<InputSlot<?>> borderInputSlots, Collection<Operator> sourceOperators, Configuration configuration) { Validate.notNull(inputSlots); Validate.notNull(sourceOperators); Validate.notNull(configuration); // Starting from the an output, find all required inputs. return new Builder(inputSlots, borderInputSlots, sourceOperators, configuration).build(); }
/** * 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())); } } }
/** * If there is no registered {@link Activator} for the {@code operator} and/or no * {@link Activation}, then these will be created, registered, and connected. * * @param operator */ private void addAndRegisterActivator(Operator operator) { // The operator should not have been processed yet. assert !this.createdActivators.containsKey(operator); // Otherwise, try to create the activator. Activator activator = this.createActivator(operator); // Register existing dependent activators. for (OutputSlot<?> outputSlot : operator.getAllOutputs()) { this.registerDependentActivations(outputSlot, activator); } // Register with required activators. this.registerAsDependentActivation(activator); }
/** * Build the {@link CardinalityEstimationTraversal}. * * @return the build {@link CardinalityEstimationTraversal} */ CardinalityEstimationTraversal build() { this.execute(); return this.result; }