Details
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 7567c82..3dfd896 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
@@ -26,7 +26,7 @@ import java.util.stream.Collectors;
*
* @author romulo
*/
-public class TraceReader extends br.ufrgs.inf.prosoft.trace.TraceReader {
+public class TraceReader extends br.ufrgs.inf.prosoft.trace.reader.TraceReader {
private static final Logger logger = Logger.getLogger(TraceReader.class.getName());
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 43e5f54..7390668 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/memoizeit/MemoizeIt.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/memoizeit/MemoizeIt.java
@@ -131,38 +131,24 @@ public class MemoizeIt {
}
// 3.2 input-output profiling
- private void refineCandidatesExhaustively() {
- logger.log(Level.INFO, "Exhaustively refining {0} candidates", this.methods.size());
- refineCandidates(Integer.MAX_VALUE);
+ private void refineCandidates() {
+ refineCandidates(true);
}
- private void refineCandidates(int depth) {
+ private void refineCandidates(boolean iteratively) {
+ 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()) {
Method method = this.methods.get(i);
- int occurrencesSize = method.getOccurrencesSize();
- if (depth < Integer.MAX_VALUE) {
- method.groupByParameter(depth);
- if (method.wasFullyExplored()) {
- this.maxDepthReached = true;
- i++;
- continue;
- }
- this.maxDepthReached = false;
+ method.removeUnusedFields(this.callGraph.getNode(method.getName()));
+ boolean refineCandidate;
+ if (iteratively) {
+ refineCandidate = refineCandidateIteratively(method);
} else {
- method.groupByParameter();
+ refineCandidate = refineCandidateExhaustively(method);
}
- int distinctOccurrencesSize = method.getDistinctOccurrencesSize();
- if (occurrencesSize == distinctOccurrencesSize) {
- this.methods.remove(i);
- continue;
- }
- if (method.isChangeful()) {
- this.methods.remove(i);
- continue;
- }
- double potentialHitRatio = method.getPotentialHitRatio();
- if (potentialHitRatio < this.minimumHitRatio) {
+ if (refineCandidate) {
this.methods.remove(i);
continue;
}
@@ -170,22 +156,36 @@ public class MemoizeIt {
}
}
- private void refineCandidatesIteratively() {
- logger.log(Level.INFO, "Iteratively refining {0} candidates", this.methods.size());
+ private boolean refineCandidateExhaustively(Method method) {
+ return refineCandidate(method, Integer.MAX_VALUE);
+ }
+
+ private boolean refineCandidateIteratively(Method method) {
+ logger.log(Level.INFO, "Iteratively refining {0}", method);
int depth = 1;
- while (true) {
+ while (!method.wasFullyExplored()) {
logger.log(Level.INFO, "Exploring depth {0}", depth);
- refineCandidates(depth);
- if (this.methods.isEmpty()) {
- logger.log(Level.INFO, "No caching candidates left to explore");
- break;
- }
- if (this.maxDepthReached) {
- logger.log(Level.INFO, "Max depth reached");
- break;
+ boolean refineCandidate = refineCandidate(method, depth);
+ if (refineCandidate) {
+ logger.log(Level.INFO, "Removing candidate");
+ return true;
}
depth *= 2;
}
+ return false;
+ }
+
+ private boolean refineCandidate(Method method, int depth) {
+ int occurrencesSize = method.getOccurrencesSize();
+ method.groupByParameter(depth);
+ int distinctOccurrencesSize = method.getDistinctOccurrencesSize();
+ if (occurrencesSize == distinctOccurrencesSize) {
+ return true;
+ }
+ if (method.isChangeful()) {
+ return true;
+ }
+ return method.getPotentialHitRatio() < this.minimumHitRatio;
}
private Collection<Method> getIndirectCallees(List<Node<String>> visited, String rootPackage, Node<String> node) {
@@ -329,7 +329,7 @@ public class MemoizeIt {
}
filterInitialCandidates();
removeUnusedFields();
- refineCandidatesIteratively();
+ refineCandidates(true);
}
public void suggestCachingImplementations() {
@@ -351,8 +351,7 @@ public class MemoizeIt {
throw new RuntimeException("Call Graph not set");
}
filterInitialCandidates();
- removeUnusedFields();
- refineCandidatesIteratively();
+ refineCandidates();
printClusters();
suggestImplementations();
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/memoizeit/Method.java b/src/main/java/br/ufrgs/inf/prosoft/memoizeit/Method.java
index 489727f..c522bba 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/memoizeit/Method.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/memoizeit/Method.java
@@ -15,7 +15,6 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
-import java.util.function.Function;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -71,20 +70,33 @@ public class Method {
}
protected void groupByParameter(int depth) {
+ logger.log(Level.INFO, "Grouping by parameters {0} occurrences of {1}", new Object[]{this.name, this.occurrences.size()});
this.groupByParameter = new HashMap<>();
- this.occurrences.forEach(occurrence -> {
- if (depth < Integer.MAX_VALUE) {
- Occurrence truncated = occurrence.getView(depth);
- this.fullyExplored = truncated == occurrence;
- occurrence = truncated;
- }
- String parameters = occurrence.getParameters().toString();
- try {
- this.groupByParameter.get(parameters).add(occurrence);
- } catch (Exception e) {
- List<Occurrence> occurrences = new ArrayList<>();
- occurrences.add(occurrence);
- this.groupByParameter.put(parameters, occurrences);
+ this.occurrences.stream().parallel().forEach(new Consumer<Occurrence>() {
+ int i = 0;
+
+ @Override
+ public void accept(Occurrence occurrence) {
+ System.out.print(".");
+ System.out.flush();
+ if (++i % 100 == 0) {
+ System.out.println();
+ }
+ if (depth < Integer.MAX_VALUE) {
+ Occurrence truncated = occurrence.getView(depth);
+ Method.this.fullyExplored = truncated == occurrence;
+ occurrence = truncated;
+ }
+ String parameters = occurrence.getParameters().toString();
+ synchronized (Method.this.groupByParameter) {
+ try {
+ Method.this.groupByParameter.get(parameters).add(occurrence);
+ } catch (Exception e) {
+ List<Occurrence> occurrences = new ArrayList<>();
+ occurrences.add(occurrence);
+ Method.this.groupByParameter.put(parameters, occurrences);
+ }
+ }
}
});
}
@@ -99,7 +111,9 @@ public class Method {
continue;
}
Occurrence firstOccurrence = entry.getValue().get(0);
- if (entry.getValue().stream().anyMatch(occurrence -> occurrence.getReturnValue() != null && !occurrence.getReturnValue().equals(firstOccurrence.getReturnValue()))) {
+ if (entry.getValue().stream()
+ .anyMatch(occurrence -> occurrence.getReturnValue() != null
+ && !occurrence.getReturnValue().equals(firstOccurrence.getReturnValue()))) {
return true;
}
}
@@ -113,7 +127,7 @@ public class Method {
}
protected void removeUnusedFields(Node<String> methodNode) {
- logger.log(Level.INFO, "Analysing fields of {0} occurrences of {1}", new Object[]{this.occurrences.size(), this.name});
+ logger.log(Level.INFO, "Removing unused fields of {0} occurrences of {1}", new Object[]{this.occurrences.size(), this.name});
if (methodNode == null) {
logger.log(Level.WARNING, "methodNode null: {0}", this.name);
return;
diff --git a/src/main/java/br/ufrgs/inf/prosoft/memoizeit/OccurrenceConcrete.java b/src/main/java/br/ufrgs/inf/prosoft/memoizeit/OccurrenceConcrete.java
index 2bad9a6..8304e55 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/memoizeit/OccurrenceConcrete.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/memoizeit/OccurrenceConcrete.java
@@ -8,11 +8,11 @@ package br.ufrgs.inf.prosoft.memoizeit;
import br.ufrgs.inf.prosoft.memoizeit.graph.Node;
import br.ufrgs.inf.prosoft.memoizeit.utils.Action;
import br.ufrgs.inf.prosoft.memoizeit.utils.ObjectUtils;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
/**
*
@@ -55,7 +55,7 @@ public class OccurrenceConcrete extends Occurrence {
@Override
protected Occurrence removeUnusedFields(Node<String> methodNode) {
- for (Parameter parameter : getParameters()) {
+ getParameters().stream().parallel().forEach((parameter) -> {
String parameterType = parameter.getType();
if (parameter.getData() instanceof Collection) {
Collection collection = (Collection) parameter.getData();
@@ -67,7 +67,7 @@ public class OccurrenceConcrete extends Occurrence {
Map<String, Object> map = (Map<String, Object>) parameter.getData();
removeUnusedFields(map, parameterType, methodNode);
}
- }
+ });
return this;
}
@@ -82,12 +82,12 @@ public class OccurrenceConcrete extends Occurrence {
this.truncated = true;
};
ObjectUtils.truncateObject(returnValue, depth, onTruncate);
- List<Parameter> parameters = new ArrayList<>();
- for (Parameter parameter : this.parameters) {
- Object parameterView = ObjectUtils.deepCopy(parameter.getData());
- ObjectUtils.truncateObject(parameterView, depth, onTruncate);
- parameters.add(new Parameter(parameter.getType(), parameterView));
- }
+ List<Parameter> parameters = this.parameters.stream()
+ .map(parameter -> {
+ Object parameterView = ObjectUtils.deepCopy(parameter.getData());
+ ObjectUtils.truncateObject(parameterView, depth, onTruncate);
+ return new Parameter(parameter.getType(), parameterView);
+ }).collect(Collectors.toList());
OccurrenceConcrete occurrenceConcrete = new OccurrenceConcrete(getInstance(), returnValue, parameters, getStartTime(), getEndTime());
return occurrenceConcrete;
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/memoizeit/OccurrenceReference.java b/src/main/java/br/ufrgs/inf/prosoft/memoizeit/OccurrenceReference.java
index d5cbc8f..1c036aa 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/memoizeit/OccurrenceReference.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/memoizeit/OccurrenceReference.java
@@ -6,7 +6,7 @@
package br.ufrgs.inf.prosoft.memoizeit;
import br.ufrgs.inf.prosoft.trace.TraceConcrete;
-import br.ufrgs.inf.prosoft.trace.Traces;
+import br.ufrgs.inf.prosoft.trace.reader.Traces;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;