memoizeit

Details

diff --git a/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/Main.java b/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/Main.java
index fc4091c..97e3311 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/Main.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/Main.java
@@ -9,9 +9,13 @@ import br.ufrgs.inf.prosoft.memoizeit.MemoizeIt;
 import br.ufrgs.inf.prosoft.memoizeit.Method;
 import br.ufrgs.inf.prosoft.memoizeit.graph.Graph;
 import br.ufrgs.inf.prosoft.trace.Trace;
+import br.ufrgs.inf.prosoft.trace.reader.Mode;
 import java.util.List;
+import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  *
@@ -24,25 +28,56 @@ public class Main {
     public static void main(String[] args) {
         System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tF %1$tT+%1$tL] [%4$-7s] [MemoizeIt] %5$s %n");
 
-        String tracePath = null;
-        String callGraphPath = null;
         if (args.length < 2) {
-            System.err.println("<TracePath> <CallGraphPath>");
+            System.err.println("--trace=<TracePath> --callgraph=<CallGraphPath>");
+            System.err.println("--trace=<TracePath> --callgraph=<CallGraphPath> [--mode=<complete|hashed|partial>] [--kernel=<iterative|exhaustive>]");
             System.exit(1);
-        } else {
-            tracePath = args[0];
-            callGraphPath = args[1];
         }
+
+        Map<String, String> arguments = Stream.of(args).map(arg -> {
+            arg = arg.replaceFirst("--", "");
+            String[] split = arg.split("=");
+            if (split.length < 2) {
+                return new String[]{"", ""};
+            }
+            return split;
+        }).collect(Collectors.toMap(array -> {
+            return array[0];
+        }, array -> {
+            return array[1];
+        }));
+
+        String tracePath = arguments.get("trace");
+        if (tracePath == null) {
+            System.err.println("<TracePath> is required");
+            System.exit(1);
+        }
+        String callGraphPath = arguments.get("callgraph");
+        if (callGraphPath == null) {
+            System.err.println("<CallGraphPath> is required");
+            System.exit(1);
+        }
+        String mode = arguments.get("mode");
+        if (mode == null) {
+            mode = "complete";
+            LOGGER.log(Level.INFO, "Using default mode: {0}", mode);
+        }
+        String kernel = arguments.get("kernel");
+        if (kernel == null) {
+            kernel = "exhaustive";
+            LOGGER.log(Level.INFO, "Using default kernel: {0}", kernel);
+        }
+
         LOGGER.log(Level.INFO, "Reading callgraph");
         Graph<String> graph = CallGraphReader.parseFile(callGraphPath);
         LOGGER.log(Level.INFO, "Reading traces");
-        List<Trace> traces = TraceReader.partiallyParseFile(tracePath);
+        List<Trace> traces = TraceReader.parseFile(tracePath, Mode.valueOf(mode.toUpperCase()));
         LOGGER.log(Level.INFO, "Grouping methods");
         List<Method> methods = TraceReader.groupByMethods(traces);
         MemoizeIt memoizeIt = new MemoizeIt();
         memoizeIt.setCallGraph(graph);
         memoizeIt.setMethods(methods);
-        memoizeIt.run();
+        memoizeIt.run(kernel.equals("iterative"), true);
         methods.forEach(System.out::println);
     }
 }
diff --git a/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/TraceReader.java b/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/TraceReader.java
index 3dfd896..2caca88 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/TraceReader.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/TraceReader.java
@@ -28,7 +28,7 @@ import java.util.stream.Collectors;
  */
 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, List<Occurrence>> methodNameHasOccurrences = new HashMap<>();
@@ -57,7 +57,7 @@ public class TraceReader extends br.ufrgs.inf.prosoft.trace.reader.TraceReader {
                     }
                 }
             } catch (Exception e) {
-                logger.log(Level.INFO, "Trace discarted: {0}", trace);
+                LOGGER.log(Level.INFO, "Trace discarted: {0}", trace);
             }
         }
         List<Method> methods = methodNameHasOccurrences.entrySet().stream().parallel()
diff --git a/src/main/java/br/ufrgs/inf/prosoft/memoizeit/MemoizeIt.java b/src/main/java/br/ufrgs/inf/prosoft/memoizeit/MemoizeIt.java
index 02fa5ae..990730a 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/memoizeit/MemoizeIt.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/memoizeit/MemoizeIt.java
@@ -37,7 +37,7 @@ public class MemoizeIt {
     // Call Graph
     private Graph<String> callGraph;
 
-    private static final Logger logger = Logger.getLogger(MemoizeIt.class.getName());
+    private static final Logger LOGGER = Logger.getLogger(MemoizeIt.class.getName());
 
     public MemoizeIt() {
         this.minimumHitRatio = 0.5;
@@ -88,7 +88,7 @@ public class MemoizeIt {
 
 //    3.1 time and frequency profiling
     private void filterInitialCandidates() {
-        logger.log(Level.INFO, "Fitering {0} initial candidates by frequency and average execution time", this.methods.size());
+        LOGGER.log(Level.INFO, "Fitering {0} initial candidates by frequency and average execution time", this.methods.size());
         int i = 0;
         while (i < this.methods.size()) {
             Method method = this.methods.get(i);
@@ -99,7 +99,7 @@ public class MemoizeIt {
             }
             i++;
         }
-        logger.log(Level.INFO, "Calculating representativity of {0} methods", this.methods.size());
+        LOGGER.log(Level.INFO, "Calculating representativity of {0} methods", this.methods.size());
         Collection<Node<String>> roots = this.callGraph.getRoots();
         roots.stream().forEach(root -> {
             Method method = getMethodByName(root.getContent());
@@ -133,7 +133,7 @@ public class MemoizeIt {
         roots = null;
         this.methods.stream().filter(method -> method.getRepresentativeness() == 0)
                 .forEach(method -> method.setRepresentativeness(1));
-        logger.log(Level.INFO, "Fitering {0} candidates by representativeness", this.methods.size());
+        LOGGER.log(Level.INFO, "Fitering {0} candidates by representativeness", this.methods.size());
         i = 0;
         while (i < this.methods.size()) {
             Method method = this.methods.get(i);
@@ -146,7 +146,7 @@ public class MemoizeIt {
     }
 
     private void removeUnusedFields() {
-        logger.log(Level.INFO, "Removing unused fields of {0} candidates left", this.methods.size());
+        LOGGER.log(Level.INFO, "Removing unused fields of {0} candidates left", this.methods.size());
         this.methods.forEach(method -> method.removeUnusedFields(this.callGraph.getNode(method.getName())));
     }
 
@@ -156,7 +156,7 @@ public class MemoizeIt {
     }
 
     private void refineCandidates(boolean iteratively) {
-        logger.log(Level.INFO, "Refining {0} candidates", this.methods.size());
+        LOGGER.log(Level.INFO, "Refining {0} candidates", this.methods.size());
         int i = 0;
         this.methods.sort((m1, m2) -> Integer.compare(m1.getOccurrencesSize(), m2.getOccurrencesSize()));
         while (i < this.methods.size()) {
@@ -181,13 +181,13 @@ public class MemoizeIt {
     }
 
     private boolean refineCandidateIteratively(Method method) {
-        logger.log(Level.INFO, "Iteratively refining {0}", method);
+        LOGGER.log(Level.INFO, "Iteratively refining {0}", method);
         int depth = 1;
         while (!method.wasFullyExplored()) {
-            logger.log(Level.INFO, "Exploring depth {0}", depth);
+            LOGGER.log(Level.INFO, "Exploring depth {0}", depth);
             boolean refineCandidate = refineCandidate(method, depth);
             if (refineCandidate) {
-                logger.log(Level.INFO, "Removing candidate");
+                LOGGER.log(Level.INFO, "Removing candidate");
                 return true;
             }
             depth *= 2;
@@ -279,10 +279,10 @@ public class MemoizeIt {
 
 //    3.3 clustering and ranking
     private void printClusters(boolean shouldRank) {
-        logger.log(Level.INFO, "Clustering {0} cacheable methods", this.methods.size());
+        LOGGER.log(Level.INFO, "Clustering {0} cacheable methods", this.methods.size());
         List<Collection<Method>> clusters = clusterMethods();
         if (shouldRank) {
-            logger.log(Level.INFO, "Ranking {0} clusters", clusters.size());
+            LOGGER.log(Level.INFO, "Ranking {0} clusters", clusters.size());
             rankClusters(clusters);
         }
         for (int i = 0; i < clusters.size(); i++) {
@@ -332,7 +332,7 @@ public class MemoizeIt {
 
 //    3.4 suggest cache implementation
     private void suggestImplementations() {
-        logger.log(Level.INFO, "Suggesting caching implementation");
+        LOGGER.log(Level.INFO, "Suggesting caching implementation");
         for (Method method : this.methods) {
             System.out.println(method.getName());
             suggestImplementation(method);
@@ -341,6 +341,10 @@ public class MemoizeIt {
     }
 
     public void removeChangefulMethods() {
+        removeChangefulMethods(false);
+    }
+
+    public void removeChangefulMethods(boolean iteratively) {
         if (this.methods == null || this.methods.isEmpty()) {
             throw new RuntimeException("Empty execution traces");
         }
@@ -353,17 +357,25 @@ public class MemoizeIt {
     }
 
     public void suggestCachingImplementations() {
+        suggestCachingImplementations(true);
+    }
+
+    public void suggestCachingImplementations(boolean shouldRank) {
         if (this.methods == null || this.methods.isEmpty()) {
             throw new RuntimeException("Empty execution traces");
         }
         if (this.callGraph == null) {
             throw new RuntimeException("Call Graph not set");
         }
-        printClusters();
+        printClusters(shouldRank);
         suggestImplementations();
     }
 
     public void run() {
+        run(false, true);
+    }
+
+    public void run(boolean iteratively, boolean shouldRank) {
         if (this.methods == null || this.methods.isEmpty()) {
             throw new RuntimeException("Empty execution traces");
         }
@@ -371,8 +383,8 @@ public class MemoizeIt {
             throw new RuntimeException("Call Graph not set");
         }
         filterInitialCandidates();
-        refineCandidates();
-        printClusters();
+        refineCandidates(iteratively);
+        printClusters(shouldRank);
         suggestImplementations();
     }
 }