diff --git a/src/main/java/br/ufrgs/inf/prosoft/aplcache/adapter/TraceReader.java b/src/main/java/br/ufrgs/inf/prosoft/aplcache/adapter/TraceReader.java
index 9dff8d3..e8b4b4c 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/aplcache/adapter/TraceReader.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/aplcache/adapter/TraceReader.java
@@ -5,13 +5,14 @@
*/
package br.ufrgs.inf.prosoft.aplcache.adapter;
+import br.ufrgs.inf.prosoft.aplcache.metadata.Method;
import br.ufrgs.inf.prosoft.aplcache.metadata.Occurrence;
import br.ufrgs.inf.prosoft.aplcache.metadata.OccurrenceConcrete;
import br.ufrgs.inf.prosoft.aplcache.metadata.OccurrenceReference;
-import br.ufrgs.inf.prosoft.aplcache.metadata.Method;
import br.ufrgs.inf.prosoft.trace.Parameter;
import br.ufrgs.inf.prosoft.trace.Trace;
import br.ufrgs.inf.prosoft.trace.TraceReference;
+
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -20,45 +21,42 @@ import java.util.logging.Logger;
import java.util.stream.Collectors;
/**
- *
* @author romulo
*/
public class TraceReader extends br.ufrgs.inf.prosoft.trace.reader.TraceReader {
- private static final Logger LOGGER = Logger.getLogger(TraceReader.class.getName());
+ private static final Logger LOGGER = Logger.getLogger(TraceReader.class.getName());
- public static List<Method> groupByMethods(List<Trace> traces) {
- Map<String, Method> methodNameHasOccurrences = new HashMap<>();
- while (!traces.isEmpty()) {
- Trace trace = traces.remove(0);
- try {
- Occurrence occurrence;
- if (trace instanceof TraceReference) {
- TraceReference traceReference = (TraceReference) trace;
- occurrence = new OccurrenceReference(traceReference.getIndex(),
- trace.getStartTime(), trace.getEndTime(), trace.getUserSession());
- } else {
- occurrence = new OccurrenceConcrete(
- trace.getParameters().stream()
- .map(Parameter::getData)
- .collect(Collectors.toList()).toArray(),
- trace.getReturn().getData(),
- trace.getStartTime(),
- trace.getEndTime(),
- trace.getUserSession()
- );
- }
- try {
- methodNameHasOccurrences.get(trace.getName()).addOccurrence(occurrence);
- } catch (Exception ex) {
- Method method = new Method(trace.getName());
- method.addOccurrence(occurrence);
- methodNameHasOccurrences.put(trace.getName(), method);
- }
- } catch (Exception e) {
- LOGGER.log(Level.INFO, "Trace discarted: {0}", trace);
- }
+ public static List<Method> groupByMethods(List<Trace> traces) {
+ Map<String, Method> methodNameHasOccurrences = new HashMap<>();
+ while (!traces.isEmpty()) {
+ Trace trace = traces.remove(0);
+ try {
+ Occurrence occurrence;
+ if (trace instanceof TraceReference) {
+ TraceReference traceReference = (TraceReference) trace;
+ occurrence = new OccurrenceReference(traceReference.getIndex(),
+ trace.getStartTime(), trace.getEndTime(), trace.getUserSession());
+ } else {
+ occurrence = new OccurrenceConcrete(
+ trace.getParameters().stream().map(Parameter::getData).toArray(),
+ trace.getReturn().getData(),
+ trace.getStartTime(),
+ trace.getEndTime(),
+ trace.getUserSession()
+ );
+ }
+ try {
+ methodNameHasOccurrences.get(trace.getName()).addOccurrence(occurrence);
+ } catch (Exception ex) {
+ Method method = new Method(trace.getName());
+ method.addOccurrence(occurrence);
+ methodNameHasOccurrences.put(trace.getName(), method);
}
- return methodNameHasOccurrences.values().stream().collect(Collectors.toList());
+ } catch (Exception e) {
+ LOGGER.log(Level.INFO, "Trace discarted: {0}", trace);
+ }
}
+ return methodNameHasOccurrences.values().stream().collect(Collectors.toList());
+ }
}
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 11e7a40..341acf0 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,7 +4,6 @@ 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.Comparator;
import java.util.List;
import java.util.logging.Level;
@@ -12,82 +11,79 @@ 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, Comparator.comparingInt(Method::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();
- }
+ 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());
+ this.methods.sort(Comparator.comparingInt(Method::getOccurrencesSize));
+ this.methods.stream().parallel().forEach(Method::calculateMetrics);
+ }
+
+ private void calculateThresholds(int kStdDev) {
+ LOGGER.log(Level.INFO, "Calculating thresholds for {0} methods", this.methods.size());
+ Thresholds.reset();
+ Thresholds.population = getPopulation();
+ this.methods.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.getStdDevExecutionTime());
+ 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) {
+ filterCacheableInputs(0, false);
+ }
+
+ public void filterCacheableInputs(int kStdDev, boolean reusable) {
+ if (reusable) removeSingleOccurrences();
+ calculateMetrics();
+ calculateThresholds(kStdDev);
+ LOGGER.log(Level.INFO, "Deciding if {0} methods are cacheable...", this.methods.size());
+ 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();
+ }
+
}
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 6fb7ad8..ffa5e76 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/aplcache/Main.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/aplcache/Main.java
@@ -14,6 +14,7 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
+
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
@@ -35,22 +36,22 @@ public class Main {
System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tF %1$tT+%1$tL] [%4$-7s] [APLCache] %5$s %n");
if (args.length < 2) {
- System.err.println("--trace=<TracePath> --output=<OutputPath> [--mode=<complete|hashed|partial>] [--k=<kStandardDeviation>] [--window=<windowSize>] [--shift=<shiftTime>] [--reusable=<true|false>]");
+ System.err.println("--trace=<TracePath>" +
+ " --output=<OutputPath>" +
+ " [--mode=<complete|hashed|partial>]" +
+ " [--k=<kStandardDeviation>]" +
+ " [--window=<windowSize>]" +
+ " [--shift=<shiftTime>]" +
+ " [--reusable=<true|false>]");
System.exit(1);
}
Map<String, String> arguments = Stream.of(args).map(arg -> {
arg = arg.replaceFirst("--", "");
int indexOf = arg.indexOf("=");
- if (indexOf == -1) {
- return new String[]{arg, ""};
- }
+ if (indexOf == -1) return new String[]{arg, ""};
return new String[]{arg.substring(0, indexOf), arg.substring(indexOf + 1)};
- }).collect(Collectors.toMap(array -> {
- return array[0];
- }, array -> {
- return array[1];
- }));
+ }).collect(Collectors.toMap(array -> array[0], array -> array[1]));
String tracePath = arguments.get("trace");
if (tracePath == null) {
@@ -73,7 +74,7 @@ public class Main {
LOGGER.log(Level.INFO, "Using default k: {0}", k);
} else {
try {
- k = Integer.valueOf(kStr);
+ k = Integer.parseInt(kStr);
} catch (NumberFormatException ex) {
System.err.println("<k> must be a number");
System.exit(1);
@@ -83,12 +84,12 @@ public class Main {
Long window = null;
try {
window = Long.valueOf(arguments.get("window"));
- } catch (NumberFormatException ex) {
+ } catch (NumberFormatException ignored) {
}
Long shift = null;
try {
shift = Long.valueOf(arguments.get("shift"));
- } catch (NumberFormatException ex) {
+ } catch (NumberFormatException ignored) {
}
String reusable = arguments.get("reusable");
@@ -106,16 +107,12 @@ public class Main {
flowchartWorkFlow.setMethods(methods);
LOGGER.log(Level.INFO, "Filtering cacheable methods");
flowchartWorkFlow.filterCacheableInputs(k, reusable.equals("true"));
- methods.forEach(method -> {
- System.out.println(method + " : " + method.groupsOfOccurrences().count() + " parameters");
- });
+ methods.forEach(method -> 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.groupsOfOccurrences().forEach(group -> {
- cacheableParameters.add(group.getParameters());
- });
+ method.groupsOfOccurrences().forEach(group -> cacheableParameters.add(group.getParameters()));
jsonCacheableParameters.add(method.getName(), cacheableParameters);
});
Gson gson = new GsonBuilder().setPrettyPrinting().create();