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