public static Tuple<OutputSlot<?>, OptimizationContext> createConcatenationKey( OutputSlot<?> outputSlot, OptimizationContext optimizationContext) { return new Tuple<>(outputSlot, optimizationContext); }
/** * Groups all {@link #planImplementations} by their {@link ExecutionOperator}s' {@link OutputSlot}s for the * {@code output}. Additionally preserves the very (nested) {@link PlanImplementation} in that {@code output} resides. * * @param output a (possibly top-level) {@link OutputSlot} that should be connected * @return a mapping that represents each element {@link #planImplementations} by a key value pair * {@code (implementing OutputSlots -> (PlanImplementation, nested PlanImplementation)} */ private MultiMap<OutputSlot<?>, Tuple<PlanImplementation, PlanImplementation>> groupImplementationsByOutput(OutputSlot<?> output) { // Sort the PlanEnumerations by their respective open InputSlot or OutputSlot. final MultiMap<OutputSlot<?>, Tuple<PlanImplementation, PlanImplementation>> basePlanGroups = new MultiMap<>(); // Find and validate implementing OutputSlots. for (PlanImplementation basePlanImplementation : this.getPlanImplementations()) { final Collection<Tuple<OutputSlot<?>, PlanImplementation>> execOpOutputsWithContext = basePlanImplementation.findExecutionOperatorOutputWithContext(output); final Tuple<OutputSlot<?>, PlanImplementation> execOpOutputWithCtx = RheemCollections.getSingleOrNull(execOpOutputsWithContext); assert execOpOutputsWithContext != null && !execOpOutputsWithContext.isEmpty() : String.format("No outputs found for %s.", output); basePlanGroups.putSingle( execOpOutputWithCtx.getField0(), new Tuple<>(basePlanImplementation, execOpOutputWithCtx.getField1()) ); } return basePlanGroups; }
@Override public Tuple<Collection<ExecutionLineageNode>, Collection<ChannelInstance>> aggregate( Tuple<Collection<ExecutionLineageNode>, Collection<ChannelInstance>> accumulator, ExecutionLineageNode node) { accumulator.getField0().add(node); return accumulator; } }
@Override public Tuple<Collection<ExecutionLineageNode>, Collection<ChannelInstance>> aggregate( Tuple<Collection<ExecutionLineageNode>, Collection<ChannelInstance>> accumulator, ChannelLineageNode node) { accumulator.getField1().add(node.getChannelInstance()); return accumulator; }
/** * Models eager execution by marking all {@link LazyExecutionLineageNode}s as executed and collecting all marked ones. * * @param inputs the input {@link ChannelInstance}s * @param outputs the output {@link ChannelInstance}s * @param operatorContext the executed {@link OptimizationContext.OperatorContext} * @return the executed {@link OptimizationContext.OperatorContext} and produced {@link ChannelInstance}s */ static Tuple<Collection<ExecutionLineageNode>, Collection<ChannelInstance>> modelEagerExecution( ChannelInstance[] inputs, ChannelInstance[] outputs, OptimizationContext.OperatorContext operatorContext) { final ExecutionLineageNode executionLineageNode = new ExecutionLineageNode(operatorContext); executionLineageNode.addAtomicExecutionFromOperatorContext(); LazyExecutionLineageNode.connectAll(inputs, executionLineageNode, outputs); final Tuple<Collection<ExecutionLineageNode>, Collection<ChannelInstance>> collectors; if (outputs.length == 0) { collectors = executionLineageNode.collectAndMark(); } else { collectors = new Tuple<>(new LinkedList<>(), new LinkedList<>()); for (ChannelInstance output : outputs) { output.getLineage().collectAndMark(collectors.getField0(), collectors.getField1()); } } return collectors; }
/** * Calculates the number of open {@link Slot}s in the concatenated {@link PlanEnumeration}. Can be used * as {@link #concatenationPriorityFunction}. * * @return the number of open {@link Slot}s */ private double countNumOfOpenSlots() { // We use the number of open slots in the concatenated PlanEnumeration. Set<Slot<?>> openSlots = new HashSet<>(); // Add all the slots from the baseEnumeration. openSlots.addAll(this.baseEnumeration.getRequestedInputSlots()); for (Tuple<OutputSlot<?>, InputSlot<?>> outputInput : this.baseEnumeration.getServingOutputSlots()) { openSlots.add(outputInput.getField0()); } // Add all the slots from the successor enumerations. for (PlanEnumeration successorEnumeration : this.activationCollector.values()) { openSlots.addAll(successorEnumeration.getRequestedInputSlots()); for (Tuple<OutputSlot<?>, InputSlot<?>> outputInput : successorEnumeration.getServingOutputSlots()) { openSlots.add(outputInput.getField0()); } } // Remove all the slots that are being connected. openSlots.remove(this.outputSlot); openSlots.removeAll(this.activationCollector.keySet()); return openSlots.size(); }
/** * @return whether the {@code enumeration} cannot be expanded anymore (i.e., all {@link PlanEnumeration#getServingOutputSlots()} and * {@link PlanEnumeration#getRequestedInputSlots()} are not connected to an adjacent {@link Slot}) */ public boolean deemsComprehensive(PlanEnumeration enumeration) { return enumeration.getServingOutputSlots().stream().allMatch( outputService -> !deemsRelevant(outputService.getField1()) ) && enumeration.getRequestedInputSlots().stream().allMatch( input -> !deemsRelevant(input) ); }
channelDescriptors = new HashSet<>(channelDescriptors); channelDescriptors.removeIf(channelDescriptor -> !channelDescriptor.isReusable()); kernelDestChannelDescriptorSetsToIndicesUpdates.add(new Tuple<>(channelDescriptors, indices)); channelsToIndicesChange.getField0(), key -> new Bitmask(this.destChannelDescriptorSets.size()) ).orInPlace(channelsToIndicesChange.getField1());
/** * Searches for a compatible {@link Class} in the given {@link List} (subclass or equal) for the given parameter * {@link Class}. If a match is found, the corresponding {@link Supplier} is used to create a default parameter. * * @param parameterClass {@link Class} of a parameter * @param defaultParameterSuppliers supply default values for various parameter {@link Class}es * @return the first match's {@link Supplier} value or {@code null} if no match was found */ private static Object getDefaultParameter(Class<?> parameterClass, List<Tuple<Class<?>, Supplier<?>>> defaultParameterSuppliers) { for (Tuple<Class<?>, Supplier<?>> defaultParameterSupplier : defaultParameterSuppliers) { if (parameterClass.isAssignableFrom(defaultParameterSupplier.getField0())) { return defaultParameterSupplier.getField1().get(); } } return null; }
public static Tuple<Operator, OptimizationContext> createKey(Operator operator, OptimizationContext optimizationContext) { return new Tuple<>(operator, optimizationContext); }
result.servingOutputSlots.removeIf(slotService -> slotService.getField0().equals(openOutputSlot));
private ConcatenationActivator getOrCreateConcatenationActivator(OutputSlot<?> output, OptimizationContext optimizationCtx) { Tuple<OutputSlot<?>, OptimizationContext> concatKey = createConcatenationKey(output, optimizationCtx); return this.concatenationActivators.computeIfAbsent( concatKey, key -> new ConcatenationActivator(key.getField0(), key.getField1())); }
public OperatorAlternativeCardinalityPusher(final OperatorAlternative operatorAlternative, final Configuration configuration ) { super(operatorAlternative); this.alternativeTraversals = operatorAlternative.getAlternatives().stream() .map(alternative -> { final CardinalityEstimationTraversal traversal = CardinalityEstimationTraversal.createPushTraversal(alternative, configuration); return new Tuple<>(alternative, traversal); }) .collect(Collectors.toList()); }
@Override protected void doExecute() { TaskActivator readyActivator; while ((readyActivator = this.readyActivators.poll()) != null) { // Execute the ExecutionTask. final ExecutionTask task = readyActivator.getTask(); final Tuple<List<ChannelInstance>, PartialExecution> executionResult = this.execute(readyActivator, task); readyActivator.dispose(); // Register the outputChannelInstances (to obtain cardinality measurements and for further stages). final List<ChannelInstance> outputChannelInstances = executionResult.getField0(); outputChannelInstances.stream().filter(Objects::nonNull).forEach(this::store); // Log executions. final PartialExecution partialExecution = executionResult.getField1(); if (partialExecution != null) { this.executionState.add(partialExecution); } // Activate successor ExecutionTasks. this.activateSuccessorTasks(task, outputChannelInstances); outputChannelInstances.stream().filter(Objects::nonNull).forEach(ChannelInstance::disposeIfUnreferenced); } }
public LoopHeadAlternativeCardinalityPusher( final LoopHeadAlternative loopHeadAlternative, Collection<InputSlot<?>> relevantInputSlots, Collection<OutputSlot<?>> relevantOutputSlots, BiFunction<OperatorAlternative.Alternative, Configuration, CardinalityPusher> pusherRetriever, final Configuration configuration ) { super(Slot.toIndices(relevantInputSlots), Slot.toIndices(relevantOutputSlots)); this.alternativePushers = loopHeadAlternative.getAlternatives().stream() .map(alternative -> { final CardinalityPusher alternativePusher = pusherRetriever.apply(alternative, configuration); return new Tuple<>(alternative, alternativePusher); }) .collect(Collectors.toList()); }
Tuple<Operator, OptimizationContext> enumerationKey = EnumerationActivator.createKey(servedOperator, optimizationCtx); EnumerationActivator enumerationActivator = this.enumerationActivators.computeIfAbsent( enumerationKey, key -> new EnumerationActivator(key.getField0(), key.getField1()) ); this.logger.trace("Registering {} for enumeration of {}.", processedEnumeration, enumerationKey.getField0());
/** * Extracts the interesting properties of a {@link PlanImplementation}. * * @param implementation whose interesting properties are requested * @return the interesting properties of the given {@code implementation} */ private static Tuple<Set<Platform>, Collection<ExecutionOperator>> getInterestingProperties(PlanImplementation implementation) { return new Tuple<>( implementation.getUtilizedPlatforms(), implementation.getInterfaceOperators() ); }