aplcache

fixed wrongly clearing occurrences, causing error on metrics.

7/9/2019 9:07:38 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 b78dcf7..ec1b496 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
@@ -1,5 +1,6 @@
 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;
@@ -25,7 +26,7 @@ public final class FlowchartWorkFlow {
         this.methods.stream().parallel().forEach(Method::calculateMetrics);
     }
 
-    private void calculateThresholds() {
+    private void calculateThresholds(int kStdDev) {
         LOGGER.log(Level.INFO, "Calculating thresholds");
         Thresholds.reset();
         Thresholds.population = getPopulation();
@@ -41,21 +42,26 @@ public final class FlowchartWorkFlow {
         LOGGER.log(Level.INFO, "StdDv shareability: {0}", Thresholds.getStdDevShareability());
         LOGGER.log(Level.INFO, "StdDv frequency: {0}", Thresholds.getStdDevFrequency());
 
-        int k = 0;
-        LOGGER.log(Level.INFO, "Using {0} stdDev to calculate thresholds...", k);
-        LOGGER.log(Level.INFO, "Threshold ExecutionTime: {0}", Thresholds.expensivenessThreshold(k));
-        LOGGER.log(Level.INFO, "Threshold HitRatio: {0}", Thresholds.hitThreshold(k));
-        LOGGER.log(Level.INFO, "Threshold MissRatio: {0}", Thresholds.missThreshold(k));
-        LOGGER.log(Level.INFO, "Threshold Shareability: {0}", Thresholds.shareabilityThreshold(k));
-        LOGGER.log(Level.INFO, "Threshold frequency: {0}", Thresholds.frequencyThreshold(k));
+        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));
     }
 
     public void filterCacheableInputs() {
+        filterCacheableInputs(0);
+    }
+
+    public void filterCacheableInputs(int kStdDev) {
         countStats();
-        calculateThresholds();
+        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();
diff --git a/src/main/java/br/ufrgs/inf/prosoft/aplcache/flowchart/metrics/CacheabilityMetrics.java b/src/main/java/br/ufrgs/inf/prosoft/aplcache/flowchart/metrics/CacheabilityMetrics.java
index 0877fb8..8e14aff 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/aplcache/flowchart/metrics/CacheabilityMetrics.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/aplcache/flowchart/metrics/CacheabilityMetrics.java
@@ -5,53 +5,33 @@ import java.util.Optional;
 
 public class CacheabilityMetrics {
 
+    public static int K_STANDARD_DEVIATION = 0;
+
     public static Optional<Boolean> isStaticData(GroupOfOccurrences groupOfOccurrences) {
-        if (groupOfOccurrences.getMetrics().getNumberOfSameOccurrences() < Thresholds.frequencyThreshold(0)) {
+        if (groupOfOccurrences.getMetrics().getNumberOfSameOccurrences() < Thresholds.frequencyThreshold(K_STANDARD_DEVIATION)) {
             return Optional.empty();
         }
-        if (groupOfOccurrences.getMetrics().getHitRatio() == 100.0) {
-            return Optional.of(true);
-        } else {
-            return Optional.of(false);
-        }
+        return Optional.of(groupOfOccurrences.getMetrics().getHitRatio() == 100.0);
     }
 
     public static Optional<Boolean> changeMoreThanUsed(GroupOfOccurrences groupOfOccurrences) {
         //+/- k sds
-        if (groupOfOccurrences.getMetrics().getMissRatio() > Thresholds.missThreshold(0)) {
-            return Optional.of(true);
-        } else {
-            return Optional.of(false);
-        }
+        return Optional.of(groupOfOccurrences.getMetrics().getMissRatio() > Thresholds.missThreshold(K_STANDARD_DEVIATION));
     }
 
     public static Optional<Boolean> usedByManyRequests(GroupOfOccurrences groupOfOccurrences) {
-        if (groupOfOccurrences.getMetrics().getNumberOfSameOccurrences() >= Thresholds.frequencyThreshold(0)) {
-            return Optional.of(true);
-        } else {
-            return Optional.of(false);
-        }
+        return Optional.of(groupOfOccurrences.getMetrics().getNumberOfSameOccurrences() >= Thresholds.frequencyThreshold(K_STANDARD_DEVIATION));
     }
 
     public static Optional<Boolean> isUserSpecific(GroupOfOccurrences groupOfOccurrences) {
         if (groupOfOccurrences.getMetrics().getAmountOfIdentifiedSameOccurences() == 0) {
             return Optional.empty();
         }
-
         //the less shareable, the more user specific
-        if (groupOfOccurrences.getMetrics().getShareability() < Thresholds.shareabilityThreshold(0)) {
-            return Optional.of(true);
-        } else {
-            return Optional.of(false);
-        }
+        return Optional.of(groupOfOccurrences.getMetrics().getShareability() < Thresholds.shareabilityThreshold(K_STANDARD_DEVIATION));
     }
 
     public static Optional<Boolean> isExpensive(GroupOfOccurrences groupOfOccurrences) {
-        if (groupOfOccurrences.getMetrics().getSameOccurrencesAverageExecutionTime() >= Thresholds.expensivenessThreshold(0)) {
-            return Optional.of(true);
-        } else {
-            return Optional.of(false);
-        }
+        return Optional.of(groupOfOccurrences.getMetrics().getSameOccurrencesAverageExecutionTime() >= Thresholds.expensivenessThreshold(K_STANDARD_DEVIATION));
     }
-
 }
diff --git a/src/main/java/br/ufrgs/inf/prosoft/aplcache/flowchart/metrics/Thresholds.java b/src/main/java/br/ufrgs/inf/prosoft/aplcache/flowchart/metrics/Thresholds.java
index 1c4f5a3..30e0668 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/aplcache/flowchart/metrics/Thresholds.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/aplcache/flowchart/metrics/Thresholds.java
@@ -45,13 +45,13 @@ public class Thresholds {
         Thresholds.sumShareability = 0;
         Thresholds.sumFrequency = 0;
 
-        Thresholds.averageFrequency = 0D;
+        Thresholds.averageFrequency = null;
 
-        Thresholds.stdDevHitRatio = 0D;
-        Thresholds.stdDevMissRatio = 0D;
-        Thresholds.stdDevExecutionTimeRatio = 0D;
-        Thresholds.stdDevFrequency = 0D;
-        Thresholds.stdDevShareability = 0D;
+        Thresholds.stdDevHitRatio = null;
+        Thresholds.stdDevMissRatio = null;
+        Thresholds.stdDevExecutionTimeRatio = null;
+        Thresholds.stdDevFrequency = null;
+        Thresholds.stdDevShareability = null;
 
         Thresholds.population = 0;
 
@@ -107,7 +107,7 @@ public class Thresholds {
         double temp = hitRatios.stream().parallel()
                 .map(hitRate -> (hitRate - mean) * (hitRate - mean))
                 .reduce(Double::sum)
-                .get();
+                .orElse(0D);
         stdDevHitRatio = Math.sqrt(temp / population);
         return stdDevHitRatio;
     }
@@ -121,10 +121,9 @@ public class Thresholds {
         }
 
         double mean = getAverageMissRatio();
-        double temp = 0;
-        for (double a : missRatios) {
-            temp += (a - mean) * (a - mean);
-        }
+        double temp = missRatios.stream().map(missRatio -> (missRatio - mean) * (missRatio - mean))
+                .reduce(Double::sum)
+                .orElse(0D);
         stdDevMissRatio = Math.sqrt(temp / population);
         return stdDevMissRatio;
     }
@@ -140,7 +139,8 @@ public class Thresholds {
         double mean = getAverageExecutionTime();
         double temp = executionTimes.stream()
                 .map(executionTime -> (executionTime - mean) * (executionTime - mean))
-                .reduce(Double::sum).get();
+                .reduce(Double::sum)
+                .orElse(0D);
         stdDevExecutionTimeRatio = Math.sqrt(temp / population);
         return stdDevExecutionTimeRatio;
     }
@@ -156,7 +156,8 @@ public class Thresholds {
         double mean = getAverageFrequency();
         double temp = frequencies.stream()
                 .map(frequency -> (frequency - mean) * (frequency - mean))
-                .reduce(Double::sum).get();
+                .reduce(Double::sum)
+                .orElse(0D);
         stdDevFrequency = Math.sqrt(temp / population);
         return stdDevFrequency;
     }
@@ -173,7 +174,7 @@ public class Thresholds {
         double temp = shareabilities.stream()
                 .map(shareability -> (shareability - mean) * (shareability - mean))
                 .reduce(Double::sum)
-                .get();
+                .orElse(0D);
         stdDevShareability = Math.sqrt(temp / population);
         return stdDevShareability;
     }
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 d81359f..639a57a 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>]");
+            System.err.println("--trace=<TracePath> --output=<OutputPath> [--mode=<complete|hashed|partial>] [--k=<kStandardDeviation>]");
             System.exit(1);
         }
 
@@ -67,6 +67,18 @@ public class Main {
             mode = "complete";
             LOGGER.log(Level.INFO, "Using default mode: {0}", mode);
         }
+        int k = 0;
+        String kStr = arguments.get("k");
+        if (kStr == null) {
+            LOGGER.log(Level.INFO, "Using default k: {0}", k);
+        } else {
+            try {
+                k = Integer.valueOf(kStr);
+            } catch (NumberFormatException ex) {
+                System.err.println("<k> must be a number");
+                System.exit(1);
+            }
+        }
 
         LOGGER.log(Level.INFO, "Reading traces");
         List<Trace> traces = TraceReader.parseFile(tracePath, Mode.valueOf(mode.toUpperCase()));
@@ -75,7 +87,7 @@ public class Main {
         FlowchartWorkFlow flowchartWorkFlow = new FlowchartWorkFlow();
         flowchartWorkFlow.setMethods(methods);
         LOGGER.log(Level.INFO, "Filtering cacheable methods");
-        flowchartWorkFlow.filterCacheableInputs();
+        flowchartWorkFlow.filterCacheableInputs(k);
         methods.forEach(method -> {
             System.out.println(method + " : " + method.getGroupsOfOccurrences().size() + " 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 1b18644..05eb37d 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
@@ -25,7 +25,7 @@ import java.util.stream.Collectors;
 public class Method {
 
     private static final Logger LOGGER = Logger.getLogger(Method.class.getName());
-    private static final boolean TRACER_VERBOSE = System.getenv("TRACER_VERBOSE") == null || !System.getenv("TRACER_VERBOSE").equals("false");
+    private static final boolean TRACER_VERBOSE = System.getenv("TRACER_VERBOSE") != null && System.getenv("TRACER_VERBOSE").equals("true");
 
     private final String name;
     private final List<Occurrence> occurrences;
@@ -94,7 +94,6 @@ public class Method {
         });
         this.groupsOfOccurrences = groupByParameter.values().stream().collect(Collectors.toList());
         groupByParameter.clear();
-        this.occurrences.clear();
     }
 
     public void calculateMetrics() {