MeasurementController.java
package de.uka.ipd.sdq.beagle.core.measurement;
import de.uka.ipd.sdq.beagle.core.AnalysisController;
import de.uka.ipd.sdq.beagle.core.Blackboard;
import de.uka.ipd.sdq.beagle.core.CodeSection;
import de.uka.ipd.sdq.beagle.core.ExternalCallParameter;
import de.uka.ipd.sdq.beagle.core.ResourceDemandingInternalAction;
import de.uka.ipd.sdq.beagle.core.SeffBranch;
import de.uka.ipd.sdq.beagle.core.SeffLoop;
import de.uka.ipd.sdq.beagle.core.measurement.order.MeasurementEvent;
import de.uka.ipd.sdq.beagle.core.measurement.order.MeasurementOrder;
import de.uka.ipd.sdq.beagle.core.measurement.order.ParameterCharacteriser;
import org.apache.commons.lang3.Validate;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Controls which measurement tool is working.
*
* <p>There is always at most one measurement tool working.
*
* @author Roman Langrehr
* @author Christoph Michelbach
* @see AnalysisController
*/
public class MeasurementController {
/**
* All {@link MeasurementTool}s this {@link MeasurementController} knows.
*/
private final Set<MeasurementTool> measurementTools;
/**
* The parameter characteriser to use for all measurements.
*/
private final ParameterCharacteriser parameterCharacteriser = new ParameterCharacteriser();
/**
* Constructs a new {@link MeasurementController}.
*
* @param measurementTools The {@link MeasurementTool}s to use. Must not be
* {@code null} and must not contain {@code null}.
*/
public MeasurementController(final Set<MeasurementTool> measurementTools) {
Validate.notNull(measurementTools);
Validate.noNullElements(measurementTools);
this.measurementTools = new HashSet<>(measurementTools);
}
/**
* Determines whether a {@link MeasurementTool} can contribute to the
* {@link Blackboard}.
*
* @param blackboard The blackboard. Must not be {@code null}.
* @return Whether a {@link MeasurementTool} can measure something which is marked as
* 'to be measured'. When {@code true} is returned, this is no guarantee that
* at least one new measurement result will be added.
*/
public boolean canMeasure(final ReadOnlyMeasurementControllerBlackboardView blackboard) {
Validate.notNull(blackboard);
int elementsToBeMeasuredInTotal = 0;
elementsToBeMeasuredInTotal += blackboard.getSeffBranchesToBeMeasured().size();
elementsToBeMeasuredInTotal += blackboard.getSeffLoopsToBeMeasured().size();
elementsToBeMeasuredInTotal += blackboard.getRdiasToBeMeasured().size();
elementsToBeMeasuredInTotal += blackboard.getExternalCallParametersToBeMeasured().size();
return elementsToBeMeasuredInTotal != 0;
}
/**
* Instructs all available {@link MeasurementTool MeasurementTools} to measure all
* items marked as “to be measured”. {@link MeasurementTool MeasurementTools} may not
* produce results for every item but will report results for all items they were able
* to measure.
*
* <p>This method may only be called, when {@link #canMeasure} returned {@code true}
* before and the {@link Blackboard} wasn't changed between this call. Otherwise the
* behaviour of this method is undefined.
*
* @param blackboard The blackboard. Must not be {@code null}.
*/
public void measure(final MeasurementControllerBlackboardView blackboard) {
Validate.notNull(blackboard);
// Read from the blackboard.
final Set<SeffBranch> seffBranches = blackboard.getSeffBranchesToBeMeasured();
final Set<SeffLoop> seffLoops = blackboard.getSeffLoopsToBeMeasured();
final Set<ResourceDemandingInternalAction> rdias = blackboard.getRdiasToBeMeasured();
final Set<ExternalCallParameter> externalCallParameters = blackboard.getExternalCallParametersToBeMeasured();
// Initialise everything needed to create a measurement order.
final Set<CodeSection> resourceDemandSections = new HashSet<CodeSection>();
final Set<CodeSection> executionSections = new HashSet<CodeSection>();
final Set<CodeSection> parameterValueSections = new HashSet<CodeSection>();
// Fill {@code executionSections}.
for (final SeffBranch seffBranch : seffBranches) {
final List<CodeSection> codeSections = seffBranch.getBranches();
for (final CodeSection codeSection : codeSections) {
executionSections.add(codeSection);
}
}
// Fill {@code executionSections}.
for (final SeffLoop seffLoop : seffLoops) {
final CodeSection codeSection = seffLoop.getLoopBody();
executionSections.add(codeSection);
}
// Fill {@code resourceDemandSections}.
for (final ResourceDemandingInternalAction rdia : rdias) {
final CodeSection codeSection = rdia.getAction();
resourceDemandSections.add(codeSection);
}
// Fill {@code parameterValueSection}.
for (final ExternalCallParameter externalCallParameter : externalCallParameters) {
final CodeSection codeSection = externalCallParameter.getCallCodeSection();
parameterValueSections.add(codeSection);
}
for (final MeasurementTool measurementTool : this.measurementTools) {
// Give every measurement tool a measurement order.
final MeasurementOrder measurementOrder =
new MeasurementOrder(parameterValueSections, resourceDemandSections, executionSections,
blackboard.getProjectInformation(), this.parameterCharacteriser);
// Get the measurement results.
final List<MeasurementEvent> measurementEvents = measurementTool.measure(measurementOrder);
// Construct a measurement event parser.
final MeasurementEventParser measurementEventParser = new MeasurementEventParser(measurementEvents);
// Add the measurement results to the blackboard.
this.addMeasurementResultsOfSeffBranchesToBlackboard(seffBranches, blackboard, measurementEventParser);
this.addMeasurementResultsOfSeffLoopsToBlackboard(seffLoops, blackboard, measurementEventParser);
this.addMeasurementResultsOfRdiasToBlackboard(rdias, blackboard, measurementEventParser);
this.addMeasurementResultsOfExternalCallParametersToBlackboard(externalCallParameters, blackboard,
measurementEventParser);
}
}
/**
* Adds all measurement results of {@code seffBranches} to the blackboard.
*
* @param seffBranches The seff branches.
* @param blackboard The blackboard.
* @param measurementEventParser A measurement result parser.
*/
private void addMeasurementResultsOfSeffBranchesToBlackboard(final Set<SeffBranch> seffBranches,
final MeasurementControllerBlackboardView blackboard, final MeasurementEventParser measurementEventParser) {
for (final SeffBranch seffBranch : seffBranches) {
final Set<BranchDecisionMeasurementResult> branchDecisionMeasurementResults =
measurementEventParser.getMeasurementResultsFor(seffBranch);
for (final BranchDecisionMeasurementResult branchDecisionMeasurementResult : branchDecisionMeasurementResults) {
blackboard.addMeasurementResultFor(seffBranch, branchDecisionMeasurementResult);
}
}
}
/**
* Adds all measurement results of {@code seffLoops} to the blackboard.
*
* @param seffLoops The seff loops.
* @param blackboard The blackboard.
* @param measurementEventParser A measurement result parser.
*/
private void addMeasurementResultsOfSeffLoopsToBlackboard(final Set<SeffLoop> seffLoops,
final MeasurementControllerBlackboardView blackboard, final MeasurementEventParser measurementEventParser) {
for (final SeffLoop seffLoop : seffLoops) {
final Set<LoopRepetitionCountMeasurementResult> loopRepetitionCountMeasurementResults =
measurementEventParser.getMeasurementResultsFor(seffLoop);
// @formatter:off
for (final LoopRepetitionCountMeasurementResult loopRepetitionCountMeasurementResult
: loopRepetitionCountMeasurementResults) {
// @formatter:on
blackboard.addMeasurementResultFor(seffLoop, loopRepetitionCountMeasurementResult);
}
}
}
/**
* Adds all measurement results of {@code rdias} to the blackboard.
*
* @param rdias The rdias.
* @param blackboard The blackboard.
* @param measurementEventParser A measurement result parser.
*/
private void addMeasurementResultsOfRdiasToBlackboard(final Set<ResourceDemandingInternalAction> rdias,
final MeasurementControllerBlackboardView blackboard, final MeasurementEventParser measurementEventParser) {
for (final ResourceDemandingInternalAction rdia : rdias) {
final Set<ResourceDemandMeasurementResult> resourceDemandMeasurementResults =
measurementEventParser.getMeasurementResultsFor(rdia);
for (final ResourceDemandMeasurementResult resourceDemandMeasurementResult : resourceDemandMeasurementResults) {
blackboard.addMeasurementResultFor(rdia, resourceDemandMeasurementResult);
}
}
}
/**
* Adds all measurement results of {@code externalCallParameters} to the blackboard.
*
* @param externalCallParameters The external call parameters.
* @param blackboard The blackboard.
* @param measurementEventParser A measurement result parser.
*/
private void addMeasurementResultsOfExternalCallParametersToBlackboard(
final Set<ExternalCallParameter> externalCallParameters, final MeasurementControllerBlackboardView blackboard,
final MeasurementEventParser measurementEventParser) {
for (final ExternalCallParameter externalCallParameter : externalCallParameters) {
final Set<ParameterChangeMeasurementResult> parameterChangeMeasurementResults =
measurementEventParser.getMeasurementResultsFor(externalCallParameter);
for (final ParameterChangeMeasurementResult parameterChangeMeasurementResult : parameterChangeMeasurementResults) {
blackboard.addMeasurementResultFor(externalCallParameter, parameterChangeMeasurementResult);
}
}
}
}