Details
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 2a269eb..5ad49c7 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
@@ -49,11 +49,26 @@ public class FlowchartWorkFlow {
LOGGER.log(Level.INFO, "\tThreshold frequency: {0}", Thresholds.frequencyThreshold(kStdDev));
}
- public void filterCacheableInputs() {
- filterCacheableInputs(0);
+ 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(int kStdDev) {
+ public void filterCacheableInputs(boolean reusable) {
+ filterCacheableInputs(0, reusable);
+ }
+
+ public void filterCacheableInputs(int kStdDev, boolean reusable) {
+ if (reusable) {
+ removeSingleOccurrences();
+ }
calculateMetrics();
calculateThresholds(kStdDev);
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 71da9dc..6fb7ad8 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/aplcache/Main.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/aplcache/Main.java
@@ -35,7 +35,7 @@ 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>]");
+ System.err.println("--trace=<TracePath> --output=<OutputPath> [--mode=<complete|hashed|partial>] [--k=<kStandardDeviation>] [--window=<windowSize>] [--shift=<shiftTime>] [--reusable=<true|false>]");
System.exit(1);
}
@@ -91,6 +91,12 @@ public class Main {
} catch (NumberFormatException ex) {
}
+ String reusable = arguments.get("reusable");
+ if (reusable == null) {
+ reusable = "false";
+ LOGGER.log(Level.INFO, "Using default reusable: {0}", reusable);
+ }
+
LOGGER.log(Level.INFO, "Reading traces");
List<Trace> traces = TraceReader.parseFile(tracePath, Mode.valueOf(mode.toUpperCase()), window, shift);
LOGGER.log(Level.INFO, "Grouping {0} traces by methods", traces.size());
@@ -99,7 +105,7 @@ public class Main {
FlowchartWorkFlow flowchartWorkFlow = new FlowchartWorkFlow();
flowchartWorkFlow.setMethods(methods);
LOGGER.log(Level.INFO, "Filtering cacheable methods");
- flowchartWorkFlow.filterCacheableInputs(k);
+ flowchartWorkFlow.filterCacheableInputs(k, reusable.equals("true"));
methods.forEach(method -> {
System.out.println(method + " : " + method.groupsOfOccurrences().count() + " parameters");
});
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 f791336..b957932 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
@@ -64,7 +64,7 @@ public class Method {
return this.groupsOfOccurrences.stream();
}
- private void groupByParameter() {
+ private void groupByInput() {
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>() {
@@ -99,8 +99,22 @@ public class Method {
this.groupsOfOccurrences = groupByParameter.values().stream().collect(Collectors.toList());
}
+ public void removeSingleOccurrences() {
+ if (this.groupsOfOccurrences == null) {
+ groupByInput();
+ }
+ int initialCountofOccurrences = this.groupsOfOccurrences.size();
+ this.groupsOfOccurrences.removeIf(groupOfOccurrences -> groupOfOccurrences.getOccurrencesSize() < 2);
+ int removedOccurrences = initialCountofOccurrences - this.groupsOfOccurrences.size();
+ if (removedOccurrences > 0) {
+ LOGGER.log(Level.INFO, "\tRemoved {0} of {1} inputs from method {2}", new Object[]{removedOccurrences, initialCountofOccurrences, this.name});
+ }
+ }
+
public void calculateMetrics() {
- groupByParameter();
+ if (this.groupsOfOccurrences == null) {
+ groupByInput();
+ }
Collections.sort(this.groupsOfOccurrences, (g1, g2) -> Integer.compare(g1.getOccurrencesSize(), g2.getOccurrencesSize()));
this.groupsOfOccurrences.stream().parallel().forEach(GroupOfOccurrences::calculateMetrics);
}