diff --git a/src/main/java/br/ufrgs/inf/prosoft/aplcache/flowchart/FlowchartWorkFlow.java b/src/main/java/br/ufrgs/inf/prosoft/aplcache/flowchart/FlowchartWorkFlow.java
index ec1b496..2a269eb 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/aplcache/flowchart/FlowchartWorkFlow.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/aplcache/flowchart/FlowchartWorkFlow.java
@@ -4,12 +4,11 @@ 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.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
-public final class FlowchartWorkFlow {
+public class FlowchartWorkFlow {
private static final Logger LOGGER = Logger.getLogger(FlowchartWorkFlow.class.getName());
@@ -20,7 +19,7 @@ public final class FlowchartWorkFlow {
return this;
}
- private void countStats() {
+ 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);
@@ -32,22 +31,22 @@ public final class FlowchartWorkFlow {
Thresholds.population = getPopulation();
this.methods.stream().forEach(Method::calculateThresholds);
- LOGGER.log(Level.INFO, "Average ExecutionTime: {0}", Thresholds.getAverageExecutionTime());
- LOGGER.log(Level.INFO, "Average HitRatio: {0}", Thresholds.getAverageHitRatio());
- LOGGER.log(Level.INFO, "Average MissRatio: {0}", Thresholds.getAverageMissRatio());
- LOGGER.log(Level.INFO, "Average shareability: {0}", Thresholds.getAverageShareability());
- LOGGER.log(Level.INFO, "StdDv ExecutionTime: {0}", Thresholds.getStdDevExecutionTimeRatio());
- LOGGER.log(Level.INFO, "StdDv HitRatio: {0}", Thresholds.getStdDevHitRatio());
- LOGGER.log(Level.INFO, "StdDv MissRatio: {0}", Thresholds.getStdDevMissRatio());
- LOGGER.log(Level.INFO, "StdDv shareability: {0}", Thresholds.getStdDevShareability());
- LOGGER.log(Level.INFO, "StdDv frequency: {0}", Thresholds.getStdDevFrequency());
+ 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, "Threshold ExecutionTime: {0}", Thresholds.expensivenessThreshold(kStdDev));
- LOGGER.log(Level.INFO, "Threshold HitRatio: {0}", Thresholds.hitThreshold(kStdDev));
- LOGGER.log(Level.INFO, "Threshold MissRatio: {0}", Thresholds.missThreshold(kStdDev));
- LOGGER.log(Level.INFO, "Threshold Shareability: {0}", Thresholds.shareabilityThreshold(kStdDev));
- LOGGER.log(Level.INFO, "Threshold frequency: {0}", Thresholds.frequencyThreshold(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));
}
public void filterCacheableInputs() {
@@ -55,21 +54,15 @@ public final class FlowchartWorkFlow {
}
public void filterCacheableInputs(int kStdDev) {
- countStats();
+ calculateMetrics();
calculateThresholds(kStdDev);
LOGGER.log(Level.INFO, "Deciding if methods are cacheable...");
CacheabilityMetrics.K_STANDARD_DEVIATION = kStdDev;
- Iterator<Method> iterator = this.methods.iterator();
- while (iterator.hasNext()) {
- Method method = iterator.next();
- method.filterCacheableInputs();
- if (method.getGroupsOfOccurrences().isEmpty()) {
- iterator.remove();
- }
- }
+ this.methods.forEach(Method::filterCacheableInputs);
+ this.methods.removeIf(method -> method.groupsOfOccurrences().count() == 0);
LOGGER.log(Level.INFO, "{0} cacheable methods detected", this.methods.size());
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/aplcache/Main.java b/src/main/java/br/ufrgs/inf/prosoft/aplcache/Main.java
index 26463fb..71da9dc 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/aplcache/Main.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/aplcache/Main.java
@@ -95,19 +95,19 @@ public class Main {
List<Trace> traces = TraceReader.parseFile(tracePath, Mode.valueOf(mode.toUpperCase()), window, shift);
LOGGER.log(Level.INFO, "Grouping {0} traces by methods", traces.size());
List<Method> methods = TraceReader.groupByMethods(traces);
- LOGGER.log(Level.INFO, "grouped traces into {1} methods", methods.size());
+ LOGGER.log(Level.INFO, "grouped traces into {0} methods", methods.size());
FlowchartWorkFlow flowchartWorkFlow = new FlowchartWorkFlow();
flowchartWorkFlow.setMethods(methods);
LOGGER.log(Level.INFO, "Filtering cacheable methods");
flowchartWorkFlow.filterCacheableInputs(k);
methods.forEach(method -> {
- System.out.println(method + " : " + method.getGroupsOfOccurrences().size() + " parameters");
+ System.out.println(method + " : " + method.groupsOfOccurrences().count() + " parameters");
});
try (FileWriter fileWriter = new FileWriter(outputPath)) {
JsonObject jsonCacheableParameters = new JsonObject();
methods.forEach(method -> {
JsonArray cacheableParameters = new JsonArray();
- method.getGroupsOfOccurrences().forEach(group -> {
+ method.groupsOfOccurrences().forEach(group -> {
cacheableParameters.add(group.getParameters());
});
jsonCacheableParameters.add(method.getName(), cacheableParameters);
diff --git a/src/main/java/br/ufrgs/inf/prosoft/aplcache/metadata/Method.java b/src/main/java/br/ufrgs/inf/prosoft/aplcache/metadata/Method.java
index 04b83fb..f791336 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/aplcache/metadata/Method.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/aplcache/metadata/Method.java
@@ -6,17 +6,16 @@
package br.ufrgs.inf.prosoft.aplcache.metadata;
import br.ufrgs.inf.prosoft.aplcache.flowchart.metrics.CacheabilityPatternDecider;
-import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
*
@@ -36,6 +35,11 @@ public class Method {
this.occurrences = new ArrayList<>();
}
+ public Method(String name, List<Occurrence> occurrences) {
+ this.name = name;
+ this.occurrences = occurrences;
+ }
+
public String getName() {
return name;
}
@@ -49,21 +53,26 @@ public class Method {
return this.occurrences.size();
}
- public List<GroupOfOccurrences> getGroupsOfOccurrences() {
- return groupsOfOccurrences;
+ public Stream<Occurrence> occurrences() {
+ if (this.occurrences == null) {
+ throw new RuntimeException("Occurrences already consumed");
+ }
+ return this.occurrences.stream();
+ }
+
+ public Stream<GroupOfOccurrences> groupsOfOccurrences() {
+ return this.groupsOfOccurrences.stream();
}
private void groupByParameter() {
- LOGGER.log(Level.INFO, "Grouping by parameters {0} occurrences of {1}", new Object[]{this.name, this.occurrences.size()});
+ LOGGER.log(Level.FINE, "Grouping by parameters {0} occurrences of {1}", new Object[]{this.name, this.occurrences.size()});
Map<String, GroupOfOccurrences> groupByParameter = new HashMap<>();
this.occurrences.stream().parallel().forEach(new Consumer<Occurrence>() {
private int i;
- private final Gson gson;
{
this.i = 0;
- this.gson = new Gson();
}
@Override
@@ -75,7 +84,7 @@ public class Method {
System.out.println();
}
}
- String parameters = this.gson.toJson(occurrence.getParameters());
+ String parameters = occurrence.getParametersSerialised();
synchronized (groupByParameter) {
try {
groupByParameter.get(parameters).addOccurrence(occurrence);
@@ -101,13 +110,7 @@ public class Method {
}
public void filterCacheableInputs() {
- Iterator<GroupOfOccurrences> iterator = this.groupsOfOccurrences.iterator();
- while (iterator.hasNext()) {
- GroupOfOccurrences groupOfOccurrences = iterator.next();
- if (!CacheabilityPatternDecider.isCacheable(groupOfOccurrences)) {
- iterator.remove();
- }
- }
+ this.groupsOfOccurrences.removeIf(CacheabilityPatternDecider::isNotCacheable);
}
@Override
diff --git a/src/main/java/br/ufrgs/inf/prosoft/aplcache/metadata/OccurrenceConcrete.java b/src/main/java/br/ufrgs/inf/prosoft/aplcache/metadata/OccurrenceConcrete.java
index 920fa3a..de90413 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/aplcache/metadata/OccurrenceConcrete.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/aplcache/metadata/OccurrenceConcrete.java
@@ -13,6 +13,7 @@ public class OccurrenceConcrete extends Occurrence {
private final Object[] parameters;
private final Object returnValue;
+ private String parametersSerialised;
public OccurrenceConcrete(Object[] arguments, Object returnedValue, long startTime, long endTime, String userId) {
super(startTime, endTime, userId);
@@ -29,4 +30,13 @@ public class OccurrenceConcrete extends Occurrence {
public Object getReturnValue() {
return this.returnValue;
}
+
+ @Override
+ public String getParametersSerialised() {
+ if (this.parametersSerialised == null) {
+ this.parametersSerialised = super.getParametersSerialised();
+ }
+ return this.parametersSerialised;
+ }
+
}