aplcache

added reusable filter argument

5/1/2020 12:37:49 AM

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);
     }