FlowchartWorkFlow.java
Home
/
src /
main /
java /
br /
ufrgs /
inf /
prosoft /
aplcache /
flowchart /
FlowchartWorkFlow.java
package br.ufrgs.inf.prosoft.aplcache.flowchart;
import br.ufrgs.inf.prosoft.aplcache.flowchart.metrics.CacheabilityMetrics;
import br.ufrgs.inf.prosoft.aplcache.flowchart.metrics.Thresholds;
import br.ufrgs.inf.prosoft.aplcache.metadata.Method;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class FlowchartWorkFlow {
private static final Logger LOGGER = Logger.getLogger(FlowchartWorkFlow.class.getName());
private List<Method> methods;
public FlowchartWorkFlow setMethods(List<Method> methods) {
this.methods = methods;
return this;
}
private void calculateMetrics() {
LOGGER.log(Level.INFO, "Counting stats of {0} methods", this.methods.size());
Collections.sort(this.methods, (m1, m2) -> Integer.compare(m1.getOccurrencesSize(), m2.getOccurrencesSize()));
this.methods.stream().parallel().forEach(Method::calculateMetrics);
}
private void calculateThresholds(int kStdDev) {
LOGGER.log(Level.INFO, "Calculating thresholds");
Thresholds.reset();
Thresholds.population = getPopulation();
this.methods.stream().forEach(Method::calculateThresholds);
LOGGER.log(Level.INFO, "\tAverage ExecutionTime: {0}", Thresholds.getAverageExecutionTime());
LOGGER.log(Level.INFO, "\tAverage HitRatio: {0}", Thresholds.getAverageHitRatio());
LOGGER.log(Level.INFO, "\tAverage MissRatio: {0}", Thresholds.getAverageMissRatio());
LOGGER.log(Level.INFO, "\tAverage shareability: {0}", Thresholds.getAverageShareability());
LOGGER.log(Level.INFO, "\tStdDv ExecutionTime: {0}", Thresholds.getStdDevExecutionTimeRatio());
LOGGER.log(Level.INFO, "\tStdDv HitRatio: {0}", Thresholds.getStdDevHitRatio());
LOGGER.log(Level.INFO, "\tStdDv MissRatio: {0}", Thresholds.getStdDevMissRatio());
LOGGER.log(Level.INFO, "\tStdDv shareability: {0}", Thresholds.getStdDevShareability());
LOGGER.log(Level.INFO, "\tStdDv frequency: {0}", Thresholds.getStdDevFrequency());
LOGGER.log(Level.INFO, "Using {0} stdDev to calculate thresholds...", kStdDev);
LOGGER.log(Level.INFO, "\tThreshold ExecutionTime: {0}", Thresholds.expensivenessThreshold(kStdDev));
LOGGER.log(Level.INFO, "\tThreshold HitRatio: {0}", Thresholds.hitThreshold(kStdDev));
LOGGER.log(Level.INFO, "\tThreshold MissRatio: {0}", Thresholds.missThreshold(kStdDev));
LOGGER.log(Level.INFO, "\tThreshold Shareability: {0}", Thresholds.shareabilityThreshold(kStdDev));
LOGGER.log(Level.INFO, "\tThreshold frequency: {0}", Thresholds.frequencyThreshold(kStdDev));
}
private void removeSingleOccurrences() {
int initialMethodsSize = this.methods.size();
LOGGER.log(Level.INFO, "Removing not reusable inputs from {0} methods", this.methods.size());
this.methods.forEach(Method::removeSingleOccurrences);
LOGGER.log(Level.INFO, "Removing not reusable methods from {0} methods", this.methods.size());
this.methods.removeIf(method -> method.groupsOfOccurrences().count() < 1);
int removedMethods = initialMethodsSize - this.methods.size();
if (removedMethods > 0) {
LOGGER.log(Level.INFO, "Removed {0} of {1} not reusable methods", new Object[]{removedMethods, initialMethodsSize});
}
}
public void filterCacheableInputs(boolean reusable) {
filterCacheableInputs(0, reusable);
}
public void filterCacheableInputs(int kStdDev, boolean reusable) {
if (reusable) {
removeSingleOccurrences();
}
calculateMetrics();
calculateThresholds(kStdDev);
LOGGER.log(Level.INFO, "Deciding if methods are cacheable...");
CacheabilityMetrics.K_STANDARD_DEVIATION = kStdDev;
this.methods.forEach(Method::filterCacheableInputs);
this.methods.removeIf(method -> method.groupsOfOccurrences().count() == 0);
LOGGER.log(Level.INFO, "{0} cacheable methods detected", this.methods.size());
}
private long getPopulation() {
return this.methods.stream().parallel()
.map(Method::getOccurrencesSize)
.reduce(Integer::sum)
.get();
}
}