Details
diff --git a/src/main/java/br/ufrgs/inf/prosoft/tfcache/configuration/Configuration.java b/src/main/java/br/ufrgs/inf/prosoft/tfcache/configuration/Configuration.java
index 0c689ed..0c64f2d 100755
--- a/src/main/java/br/ufrgs/inf/prosoft/tfcache/configuration/Configuration.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/configuration/Configuration.java
@@ -1,6 +1,9 @@
package br.ufrgs.inf.prosoft.tfcache.configuration;
import com.google.gson.JsonObject;
+
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -16,6 +19,7 @@ public class Configuration {
private static String changeability = "allow";
private static String staleness = "ignore";
private static String kernel = "exhaustive";
+ private static ArrayList<Double> preferences = new ArrayList<>(List.of(1D, 0D));
private static boolean verbose = false;
public static void process(String[] args) {
@@ -35,6 +39,11 @@ public class Configuration {
setStaleness(arguments.get("staleness"));
setKernel(arguments.get("kernel"));
setVerbose(arguments.get("verbose"));
+ setPreferences(arguments.get("preferences"));
+ }
+
+ public static String getInput() {
+ return input;
}
public static void setInput(String input) {
@@ -45,8 +54,8 @@ public class Configuration {
Configuration.input = input;
}
- public static String getInput() {
- return input;
+ public static String getStore() {
+ return store;
}
public static void setStore(String store) {
@@ -61,8 +70,8 @@ public class Configuration {
Configuration.store = store;
}
- public static String getStore() {
- return store;
+ public static String getLevel() {
+ return level;
}
public static void setLevel(String level) {
@@ -77,8 +86,8 @@ public class Configuration {
Configuration.level = level;
}
- public static String getLevel() {
- return level;
+ public static String getOutput() {
+ return output;
}
public static void setOutput(String output) {
@@ -88,8 +97,8 @@ public class Configuration {
Configuration.output = output;
}
- public static String getOutput() {
- return output;
+ public static String getChangeability() {
+ return changeability;
}
public static void setChangeability(String changeability) {
@@ -104,8 +113,8 @@ public class Configuration {
Configuration.changeability = changeability;
}
- public static String getChangeability() {
- return changeability;
+ public static String getStaleness() {
+ return staleness;
}
public static void setStaleness(String staleness) {
@@ -120,8 +129,8 @@ public class Configuration {
Configuration.staleness = staleness;
}
- public static String getStaleness() {
- return staleness;
+ public static String getKernel() {
+ return kernel;
}
public static void setKernel(String kernel) {
@@ -136,8 +145,8 @@ public class Configuration {
Configuration.kernel = kernel;
}
- public static String getKernel() {
- return kernel;
+ public static boolean getVerbose() {
+ return verbose;
}
public static void setVerbose(String verbose) {
@@ -151,8 +160,23 @@ public class Configuration {
Configuration.verbose = verbose.equals("true");
}
- public static boolean getVerbose() {
- return verbose;
+ public static List<Double> getPreferences() {
+ return preferences;
+ }
+
+ public static void setPreferences(String preferences) {
+ if (preferences == null) {
+ LOGGER.info("using default preferences");
+ return;
+ }
+ String[] split = preferences.split(",");
+ if (split.length != 2) {
+ LOGGER.severe("Wrong input for preferences");
+ System.exit(1);
+ }
+ Configuration.preferences.clear();
+ Configuration.preferences.add(Double.valueOf(split[0]));
+ Configuration.preferences.add(Double.valueOf(split[1]));
}
public static String getUUID() {
diff --git a/src/main/java/br/ufrgs/inf/prosoft/tfcache/Main.java b/src/main/java/br/ufrgs/inf/prosoft/tfcache/Main.java
index 60c0f04..b385b41 100755
--- a/src/main/java/br/ufrgs/inf/prosoft/tfcache/Main.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/Main.java
@@ -9,12 +9,12 @@ import br.ufrgs.inf.prosoft.tfcache.adapter.TraceReader;
import br.ufrgs.inf.prosoft.tfcache.configuration.Configuration;
import br.ufrgs.inf.prosoft.tfcache.metadata.Method;
import br.ufrgs.inf.prosoft.trace.Trace;
+
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
- *
* @author romulo
*/
public class Main {
@@ -25,7 +25,15 @@ public class Main {
System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tF %1$tT+%1$tL] [%4$-7s] [TFCache] %5$s %n");
if (args.length < 1) {
- System.err.println("--trace=<TracePath> [--store=<storePath>] [--level=<method|input>] [--output=<outputPath>] [--changeability=<allow|deny>] [--staleness=<ignore|shrink>] [--kernel=<exhaustive|optimised>|test] [--verbose=<false|true>]");
+ System.err.println("--trace=<TracePath> " +
+ "[--store=<storePath>] " +
+ "[--level=<method|input>] " +
+ "[--output=<outputPath>] " +
+ "[--changeability=<allow|deny>] " +
+ "[--staleness=<ignore|shrink>] " +
+ "[--kernel=<exhaustive|optimised>|test] " +
+ "[--preferences=(savedTime)0..1,0..1(idleTime)] " +
+ "[--verbose=<false|true>]");
System.exit(1);
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/tfcache/metadata/GroupOfOccurrences.java b/src/main/java/br/ufrgs/inf/prosoft/tfcache/metadata/GroupOfOccurrences.java
index 25ba662..65d1d7d 100755
--- a/src/main/java/br/ufrgs/inf/prosoft/tfcache/metadata/GroupOfOccurrences.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/metadata/GroupOfOccurrences.java
@@ -6,8 +6,12 @@
package br.ufrgs.inf.prosoft.tfcache.metadata;
import br.ufrgs.inf.prosoft.tfcache.Metrics;
+import br.ufrgs.inf.prosoft.tfcache.Pareto;
import br.ufrgs.inf.prosoft.tfcache.Simulator;
+import br.ufrgs.inf.prosoft.tfcache.configuration.Configuration;
+
import java.math.BigDecimal;
+import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
@@ -26,7 +30,7 @@ public class GroupOfOccurrences {
private final List<Occurrence> occurrences;
private final String parameters;
- private Metrics bestMetrics;
+ private Pareto pareto;
public GroupOfOccurrences(String parameters, List<Occurrence> occurrences) {
this.parameters = parameters;
@@ -42,10 +46,10 @@ public class GroupOfOccurrences {
}
public Metrics getBestMetrics() {
- if (this.bestMetrics == null) {
- throw new RuntimeException("hitsPerTimeInCache must be calculated");
+ if (this.pareto == null) {
+ throw new RuntimeException("simulation must be executed");
}
- return this.bestMetrics;
+ return this.pareto.getBestMetrics();
}
public long getTtl() {
@@ -60,7 +64,7 @@ public class GroupOfOccurrences {
return getBestMetrics().getStales();
}
- public long getSavedTime() {
+ public double getSavedTime() {
return getBestMetrics().getSavedTime();
}
@@ -84,16 +88,20 @@ public class GroupOfOccurrences {
return false;
}
- public void calculateHitsPerTimeInCache() {
- if (this.bestMetrics != null) {
- LOGGER.log(Level.WARNING, "HitsPerTimeInCache already calculated");
+ public void calculateMetrics() {
+ if (this.pareto != null) {
+ LOGGER.log(Level.WARNING, "metrics already calculated");
}
if (this.occurrences.size() < 2) {
throw new RuntimeException("Not reusable input");
}
- this.occurrences.sort((occurrence1, occurrence2) -> Long.compare(occurrence1.getStartTime(), occurrence2.getStartTime()));
- this.bestMetrics = new Metrics();
- Simulator.simulate(this.occurrences, this.bestMetrics);
+ this.occurrences.sort(Comparator.comparingLong(Occurrence::getStartTime));
+ this.pareto = new Pareto();
+ Simulator.simulate(this.occurrences, this.pareto);
+ if (Configuration.getVerbose()) {
+ this.pareto.values().forEach(it ->
+ System.out.println(Configuration.getInput() + "," + it.getTtl() + "," + it.getSavedTime() + "," + it.getHits() + "," + it.getTimeInCache()));
+ }
}
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/tfcache/metadata/Method.java b/src/main/java/br/ufrgs/inf/prosoft/tfcache/metadata/Method.java
index f30b16e..84fd1aa 100755
--- a/src/main/java/br/ufrgs/inf/prosoft/tfcache/metadata/Method.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/metadata/Method.java
@@ -6,6 +6,7 @@
package br.ufrgs.inf.prosoft.tfcache.metadata;
import br.ufrgs.inf.prosoft.tfcache.Metrics;
+import br.ufrgs.inf.prosoft.tfcache.Pareto;
import br.ufrgs.inf.prosoft.tfcache.Simulator;
import br.ufrgs.inf.prosoft.tfcache.StorageManager;
import br.ufrgs.inf.prosoft.tfcache.configuration.Configuration;
@@ -27,12 +28,12 @@ public class Method {
private static final Logger LOGGER = Logger.getLogger(Method.class.getName());
private final String name;
- private List<Occurrence> occurrences;
+ private final List<Occurrence> occurrences;
private List<GroupOfOccurrences> groupsOfOccurrences;
private Integer countChangeableGroups;
- private Metrics bestMetrics;
+ private Pareto pareto;
public Method(String name, List<Occurrence> occurrences) {
this.name = name;
@@ -50,7 +51,7 @@ public class Method {
throw new RuntimeException("Occurrences cannot be null");
}
Map<String, List<Occurrence>> inputHasOccurrences = new ConcurrentHashMap<>();
- occurrences.stream().forEach(occurrence -> {
+ occurrences.forEach(occurrence -> {
String parameters = occurrence.getParametersSerialised();
inputHasOccurrences.compute(parameters, (key, oldValue) -> {
@@ -69,21 +70,21 @@ public class Method {
}
public Metrics getBestMetrics() {
- return this.bestMetrics;
+ return this.pareto.getBestMetrics();
}
- public long getEstimatedSavedTime() {
+ public double getEstimatedSavedTime() {
if (getBestMetrics() != null) {
return getBestMetrics().getSavedTime();
}
- return groupsOfOccurrences().map(group -> group.getSavedTime()).reduce(Long::sum).orElse(0L);
+ return groupsOfOccurrences().map(GroupOfOccurrences::getSavedTime).reduce(Double::sum).orElse(0D);
}
public BigDecimal getEstimatedSavedTimePerTimeInCache() {
if (getBestMetrics() != null) {
return getBestMetrics().getSavedTimePerTimeInCache();
}
- GroupOfOccurrences max = groupsOfOccurrences().max((group1, group2) -> group1.getSavedTimePerTimeInCache().compareTo(group2.getSavedTimePerTimeInCache())).get();
+ GroupOfOccurrences max = groupsOfOccurrences().max(Comparator.comparing(GroupOfOccurrences::getSavedTimePerTimeInCache)).orElseThrow();
return max.getSavedTimePerTimeInCache();
}
@@ -99,7 +100,7 @@ public class Method {
if (this.groupsOfOccurrences == null) {
throw new RuntimeException("groupsOfOccurrences is null");
}
- return this.groupsOfOccurrences.stream().map(group -> group.getOccurrencesSize()).reduce(Integer::sum).orElse(0);
+ return this.groupsOfOccurrences.stream().map(GroupOfOccurrences::getOccurrencesSize).reduce(Integer::sum).orElse(0);
}
return this.occurrences.size();
}
@@ -181,18 +182,23 @@ public class Method {
}
public void recommendTTL() {
- if (this.bestMetrics != null) {
- LOGGER.log(Level.WARNING, "SavedTimePerTimeInCache already calculated");
+ if (this.pareto != null) {
+ LOGGER.log(Level.WARNING, "metrics already calculated");
}
if (this.occurrences == null) {
throw new RuntimeException("groupByInputs called. Cannot proceed");
}
- this.bestMetrics = new Metrics();
+ this.pareto = new Pareto();
if (this.occurrences.size() < 2) {
return;
}
this.occurrences.sort(Comparator.comparingLong(Occurrence::getStartTime));
- Simulator.simulate(this.occurrences, this.bestMetrics);
+ Simulator.simulate(this.occurrences, this.pareto);
+ if (Configuration.getVerbose()) {
+ String application = Configuration.getInput().split(",")[0];
+ this.pareto.values().forEach(it ->
+ System.out.println(application + "," + name + "," + it.getTtl() + "," + it.getSavedTime() + "," + it.getHits() + "," + it.getTimeInCache()));
+ }
}
public void recommendTTLPerInput() {
@@ -202,16 +208,19 @@ public class Method {
}
if (Configuration.getVerbose()) {
System.out.println("=== " + getName() + " ===");
+ Configuration.setInput(Configuration.getInput().split(",")[0] + "," + getName() + ",");
+ groupsOfOccurrences().forEach(GroupOfOccurrences::calculateMetrics);
+ } else {
+ groupsOfOccurrences().parallel().forEach(GroupOfOccurrences::calculateMetrics);
}
- groupsOfOccurrences().parallel().forEach(GroupOfOccurrences::calculateHitsPerTimeInCache);
String uuid = Configuration.getUUID().replace("level:input", "level:method");
- Metrics metrics = StorageManager.get(uuid, this.occurrences);
- if (this.bestMetrics == null && metrics != null) {
- this.bestMetrics = metrics;
+ Pareto pareto = StorageManager.get(uuid, this.occurrences);
+ if (this.pareto == null && pareto != null) {
+ this.pareto = pareto;
}
}
- public void removeNotRecommededInputs() {
+ public void removeNotRecommendedInputs() {
if (this.groupsOfOccurrences == null) {
throw new RuntimeException("Recommendations not called");
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/tfcache/Metrics.java b/src/main/java/br/ufrgs/inf/prosoft/tfcache/Metrics.java
old mode 100644
new mode 100755
index 4439e6a..db1120b
--- a/src/main/java/br/ufrgs/inf/prosoft/tfcache/Metrics.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/Metrics.java
@@ -5,17 +5,17 @@
*/
package br.ufrgs.inf.prosoft.tfcache;
+import br.ufrgs.inf.prosoft.tfcache.configuration.Configuration;
+import br.ufrgs.inf.prosoft.tfcache.metadata.Occurrence;
+
import java.math.BigDecimal;
-import java.math.BigInteger;
import java.math.MathContext;
-import java.util.Collection;
-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;
/**
- *
* @author romulo
*/
public class Metrics implements Comparable<Metrics> {
@@ -23,27 +23,60 @@ public class Metrics implements Comparable<Metrics> {
private long ttl;
private long hits;
private long timeInCache;
+ private long computationTime;
private long stales;
- private long savedTime;
- private BigDecimal savedTimePerTimeInCache;
+ private double savedTime;
+
+ private transient String uuid;
+ private transient Double idleTime;
+
+ protected Metrics() {
+ Logger.getLogger(Metrics.class.getName()).log(Level.FINEST, "returning empty metrics");
+ }
- public Metrics() {
- this.savedTimePerTimeInCache = new BigDecimal(BigInteger.ZERO);
+ public Metrics(long ttl, long hits, long timeInCache, long computationTime, long stales, double savedTime, String uuid) {
+ this(ttl, hits, timeInCache, computationTime, stales, savedTime);
+ this.uuid = uuid;
}
- public Metrics(long ttl, long hits, long timeInCache, long stales, long savedTime) {
- if (ttl < 0 || hits < 0 || timeInCache < 0 || stales < 0 || savedTime < 0) {
- throw new RuntimeException("Metrics cannot be under zero");
+ public Metrics(long ttl, long hits, long timeInCache, long computationTime, long stales, double savedTime) {
+ if (ttl < 0 || hits < 0 || timeInCache < 0 || computationTime < 0 || stales < 0 || savedTime < 0) {
+ throw new RuntimeException("Metrics cannot be under zero."
+ + " TTL: " + ttl
+ + " hits: " + hits
+ + " timeInCache: " + timeInCache
+ + " computationTime: " + computationTime
+ + " stales: " + stales
+ + " savedTime: " + savedTime);
}
- if (timeInCache == 0) {
- throw new RuntimeException("timeInCache should not be zero");
+ if (ttl == 0 || computationTime == 0 || timeInCache == 0) {
+ throw new RuntimeException("Metrics cannot be zero."
+ + " TTL: " + ttl
+ + " timeInCache: " + timeInCache
+ + " computationTime: " + computationTime);
}
this.ttl = ttl;
this.hits = hits;
this.timeInCache = timeInCache;
+ this.computationTime = computationTime;
this.stales = stales;
this.savedTime = savedTime;
- this.savedTimePerTimeInCache = new BigDecimal(this.savedTime).divide(new BigDecimal(this.timeInCache), MathContext.DECIMAL128);
+ }
+
+ public static String getUUID(Stream<Occurrence> occurrences) {
+ return occurrences.map(it -> it.getStartTime() + ":" + it.getEndTime()).collect(Collectors.joining(","));
+ }
+
+ private static double calculateEuclideanDistance(double x1, double y1, double x2, double y2) {
+ return Math.sqrt(Math.pow(x1 - x2, 2) - Math.pow(y1, y2));
+ }
+
+ public double calculateEuclideanDistance(double objectiveSavedTime, double objectiveIdleTime) {
+ return calculateEuclideanDistance(getSavedTime(), getIdleTime(), objectiveSavedTime, objectiveIdleTime);
+ }
+
+ public String getUUID() {
+ return uuid;
}
public long getTtl() {
@@ -58,107 +91,70 @@ public class Metrics implements Comparable<Metrics> {
return timeInCache;
}
+ public double getIdleTime() {
+ if (this.idleTime == null) {
+ this.idleTime = (double) timeInCache - hits;
+ }
+ return this.idleTime;
+ }
+
+ public long getComputationTime() {
+ return computationTime;
+ }
+
public long getStales() {
return this.stales;
}
- public long getSavedTime() {
+ public double getSavedTime() {
return this.savedTime;
}
public BigDecimal getSavedTimePerTimeInCache() {
- return this.savedTimePerTimeInCache;
+ if (this.timeInCache + this.computationTime == 0) {
+ return BigDecimal.ZERO;
+ }
+ return new BigDecimal(this.savedTime)
+ .divide(new BigDecimal(this.timeInCache + this.computationTime), MathContext.DECIMAL128);
}
- public synchronized void keepBestMetrics(Metrics metrics) {
- keepBestMetrics(metrics.ttl, metrics.hits, metrics.timeInCache, metrics.stales, metrics.savedTime);
+ public Double getDifference() {
+ return Configuration.getPreferences().get(0) * getSavedTime() - Configuration.getPreferences().get(1) * getIdleTime();
}
- public synchronized void keepBestMetrics(long ttl, long hits, long timeInCache, long stales, long savedTime) {
- if (ttl < 0 || hits < 0 || timeInCache < 0 || stales < 0 || savedTime < 0) {
- throw new RuntimeException("Metrics cannot be under zero. TTL: " + ttl
- + " hits: " + hits
- + " timeInCache: " + timeInCache
- + " stales: " + stales
- + " savedTime: " + savedTime);
+ public Metrics getNormalised(double savedTime, double idleTime) {
+ if (savedTime < 0 || savedTime > 1) {
+ throw new RuntimeException("wrong savedTime");
}
- if (ttl == 0 || hits == 0 || savedTime == 0) {
- return;
- }
- if (timeInCache == 0) {
- throw new RuntimeException("timeInCache should not be zero");
- }
- BigDecimal savedTimePerTimeInCache = new BigDecimal(savedTime).divide(new BigDecimal(timeInCache), MathContext.DECIMAL128);
- if (this.ttl == 0 || compareTo(ttl, hits, timeInCache, stales, savedTime, savedTimePerTimeInCache) == -1) {
- this.ttl = ttl;
- this.hits = hits;
- this.timeInCache = timeInCache;
- this.stales = stales;
- this.savedTime = savedTime;
- this.savedTimePerTimeInCache = savedTimePerTimeInCache;
+ if (idleTime < 0 || idleTime > 1) {
+ throw new RuntimeException("wrong idleTime");
}
- }
-
- public static void removeDominatedMetrics(Collection<Metrics> allMetrics) {
- Map<Long, List<Metrics>> groupBySavedTime = allMetrics.stream().collect(Collectors.groupingBy(Metrics::getSavedTime));
- groupBySavedTime.remove(0L);
- groupBySavedTime.forEach((savedTime, value) -> {
- Metrics max = value.stream().max(Metrics::compareTo).get();
- value.removeIf(metric -> metric.getSavedTimePerTimeInCache().compareTo(max.getSavedTimePerTimeInCache()) == -1);
- });
-
- List<Metrics> localMaxima = groupBySavedTime.entrySet().stream()
- .map(entry -> entry.getValue().stream())
- .reduce(Stream::concat)
- .orElse(Stream.empty())
- .collect(Collectors.toList());
-
- allMetrics.removeIf(metrics -> !localMaxima.contains(metrics));
+ Metrics metrics = new Metrics(ttl,
+ hits,
+ timeInCache,
+ computationTime,
+ stales,
+ savedTime,
+ uuid);
+ metrics.idleTime = idleTime;
+ return metrics;
}
@Override
public int compareTo(Metrics other) {
- return compareTo(other.ttl, other.hits, other.timeInCache, other.stales, other.savedTime, other.savedTimePerTimeInCache);
- }
-
- private int compareTo(long ttl, long hits, long timeInCache, long stales, long savedTime, BigDecimal savedTimePerTimeInCache) {
- if (getSavedTimePerTimeInCache().compareTo(savedTimePerTimeInCache) == 1) {
- return 1;
- }
- if (getSavedTimePerTimeInCache().compareTo(savedTimePerTimeInCache) == -1) {
- return -1;
- }
- if (this.stales < stales) {
- return 1;
+ if (getTtl() == other.getTtl()) {
+ return 0;
}
- if (this.stales > stales) {
- return -1;
- }
- if (this.savedTime > savedTime) {
- return 1;
- }
- if (this.savedTime < savedTime) {
- return -1;
- }
- if (this.hits > hits) {
- return 1;
- }
- if (this.hits < hits) {
- return -1;
- }
- if (this.ttl < ttl) {
- return 1;
- }
- if (this.ttl > ttl) {
- return -1;
+ if (getSavedTime() == other.getSavedTime() && getIdleTime() == other.getIdleTime()) {
+ throw new RuntimeException("different ttls leading to same metrics");
}
- if (this.timeInCache < timeInCache) {
+ if (getSavedTime() >= other.getSavedTime() && getIdleTime() <= other.getIdleTime()) {
return 1;
}
- if (this.timeInCache > timeInCache) {
+ if (getSavedTime() <= other.getSavedTime() && getIdleTime() >= other.getIdleTime()) {
return -1;
}
- return 0;
+ throw new RuntimeException("comparing pareto metrics");
}
@Override
@@ -183,7 +179,8 @@ public class Metrics implements Comparable<Metrics> {
+ " Stales: " + this.stales
+ " Hits: " + this.hits
+ " SavedTime: " + this.savedTime
- + " TimeInCache: " + this.timeInCache;
+ + " TimeInCache: " + this.timeInCache
+ + " ComputationTime: " + this.computationTime;
}
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/tfcache/Pareto.java b/src/main/java/br/ufrgs/inf/prosoft/tfcache/Pareto.java
new file mode 100644
index 0000000..065a9a7
--- /dev/null
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/Pareto.java
@@ -0,0 +1,89 @@
+package br.ufrgs.inf.prosoft.tfcache;
+
+import br.ufrgs.inf.prosoft.tfcache.configuration.Configuration;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class Pareto {
+
+ private final Map<Double, Metrics> savedTimeHasMetrics;
+
+ public Pareto() {
+ savedTimeHasMetrics = new ConcurrentHashMap<>();
+ }
+
+ public Pareto(List<Metrics> metrics) {
+ this();
+ metrics.forEach(this::addIfPareto);
+ }
+
+ public static void removeDominatedMetrics(Collection<Metrics> allMetrics) {
+ Map<Double, List<Metrics>> groupBySavedTime = allMetrics.stream().collect(Collectors.groupingBy(Metrics::getSavedTime));
+ groupBySavedTime.remove(0L);
+ groupBySavedTime.forEach((savedTime, metrics) -> {
+ double minIdleTime = metrics.stream().mapToDouble(Metrics::getIdleTime).min().orElse(0);
+ metrics.removeIf(metric -> metric.getIdleTime() > minIdleTime);
+ });
+
+ List<Metrics> localMaxima = groupBySavedTime.values().stream()
+ .map(Collection::stream)
+ .reduce(Stream::concat)
+ .orElse(Stream.empty())
+ .collect(Collectors.toList());
+
+ allMetrics.removeIf(metrics -> !localMaxima.contains(metrics));
+ }
+
+ public synchronized void addIfPareto(Metrics metrics) {
+ if (metrics.getSavedTime() == 0) {
+ return;
+ }
+ savedTimeHasMetrics.merge(metrics.getSavedTime(), metrics, (existing, incoming) -> existing.getIdleTime() < incoming.getIdleTime() ? existing : incoming);
+ }
+
+ public Collection<Metrics> values() {
+ return savedTimeHasMetrics.values();
+ }
+
+ public Set<Long> getTtls() {
+ return values().stream().map(Metrics::getTtl).collect(Collectors.toSet());
+ }
+
+ public Stream<Metrics> getNormalised() {
+ double minSavedTime = values().stream().mapToDouble(Metrics::getSavedTime).min().orElseThrow();
+ double maxSavedTime = values().stream().mapToDouble(Metrics::getSavedTime).max().orElseThrow();
+ double distanceSavedTime = maxSavedTime - minSavedTime;
+ double minIdleTime = values().stream().mapToDouble(Metrics::getIdleTime).min().orElseThrow();
+ double maxIdleTime = values().stream().mapToDouble(Metrics::getIdleTime).max().orElseThrow();
+ double distanceIdleTime = maxIdleTime - minIdleTime;
+
+ return values().stream().map(it -> {
+ double normalisedSavedTime = (it.getSavedTime() - minSavedTime) / distanceSavedTime;
+ double normalisedIdleTime = (it.getIdleTime() - minIdleTime) / distanceIdleTime;
+ return it.getNormalised(normalisedSavedTime, normalisedIdleTime);
+ });
+ }
+
+ public Metrics getBestMetrics() {
+ return getBestMetrics(Configuration.getPreferences().get(0), Configuration.getPreferences().get(1));
+ }
+
+ private Metrics getBestMetrics(double percentageObjectiveSavedTime, double percentageObjectiveIdleTime) {
+ if (percentageObjectiveSavedTime < 0 || percentageObjectiveSavedTime > 1) {
+ throw new RuntimeException("invalid objective saved time");
+ }
+ if (percentageObjectiveIdleTime < 0 || percentageObjectiveIdleTime > 1) {
+ throw new RuntimeException("invalid objective idle time");
+ }
+ if (savedTimeHasMetrics.isEmpty()) {
+ return new Metrics();
+ }
+ double minIdleTime = values().stream().mapToDouble(Metrics::getIdleTime).min().orElseThrow() * percentageObjectiveIdleTime;
+ double maxSavedTime = values().stream().mapToDouble(Metrics::getSavedTime).max().orElseThrow() * percentageObjectiveSavedTime;
+ return values().stream().min(Comparator.comparingDouble(it -> it.calculateEuclideanDistance(maxSavedTime, minIdleTime))).orElseThrow();
+ }
+
+}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/tfcache/Simulator.java b/src/main/java/br/ufrgs/inf/prosoft/tfcache/Simulator.java
old mode 100644
new mode 100755
index 814d241..a17aae1
--- a/src/main/java/br/ufrgs/inf/prosoft/tfcache/Simulator.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/Simulator.java
@@ -8,86 +8,72 @@ package br.ufrgs.inf.prosoft.tfcache;
import br.ufrgs.inf.prosoft.tfcache.configuration.Configuration;
import br.ufrgs.inf.prosoft.tfcache.metadata.Method;
import br.ufrgs.inf.prosoft.tfcache.metadata.Occurrence;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
+
+import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
import java.util.stream.Stream;
/**
- *
* @author romulo
*/
public class Simulator {
- private final Metrics metrics;
+ private final Pareto pareto;
public Simulator() {
- this.metrics = new Metrics();
- }
-
- public Metrics getMetrics() {
- return metrics;
- }
-
- public void simulate(List<Occurrence> occurrences) {
- simulate(occurrences, this.metrics);
+ this.pareto = new Pareto();
}
- public void simulate(Stream<Occurrence> occurrences, long ttl) {
- simulate(occurrences, ttl, this.metrics);
- }
-
- public static void simulate(List<Occurrence> occurrences, Metrics metrics) {
- Metrics computeIfAbsent = StorageManager.computeIfAbsent(occurrences, () -> {
+ public static void simulate(List<Occurrence> occurrences, Pareto pareto) {
+ Pareto computeIfAbsent = StorageManager.computeIfAbsent(occurrences, () -> {
switch (Configuration.getKernel()) {
case "exhaustive":
- simulate(occurrences, generateAllTTLs(occurrences), metrics);
+ simulate(occurrences, generateAllTTLs(occurrences), pareto);
break;
case "optimised":
- simulate(occurrences, generateTTLsOfInterest(occurrences), metrics);
+ simulate(occurrences, generateTTLsOfInterest(occurrences), pareto);
break;
default:
testKernels(occurrences);
break;
}
- return metrics;
+ return pareto;
});
- metrics.keepBestMetrics(computeIfAbsent);
+ computeIfAbsent.values().forEach(pareto::addIfPareto);
}
- public static void simulate(List<Occurrence> occurrences, Stream<Long> ttls, Metrics metrics) {
- ttls.forEach(actualTTL -> {
- simulate(occurrences.stream(), actualTTL, metrics);
- });
+ public static void simulate(List<Occurrence> occurrences, Stream<Long> ttls, Pareto pareto) {
+ ttls.forEach(actualTTL -> simulate(occurrences.stream(), actualTTL, pareto));
}
- public static void simulate(Stream<Occurrence> occurrences, long ttl, Metrics metrics) {
+ public static void simulate(Stream<Occurrence> occurrences, long ttl, Pareto pareto) {
Map<String, Long> inputHasCachedTime = new HashMap<>();
Map<String, Object> inputHasOutput = new HashMap<>();
- long simulationSavedTime = 0;
+ long blindedSavedTime = 0;
long realSavedTime = 0;
long hits = 0;
+ long computationTime = 0;
long timeInCache = 0;
long stales = 0;
Iterator<Occurrence> iterator = occurrences.iterator();
while (iterator.hasNext()) {
Occurrence occurrence = iterator.next();
- long adjustedStartTime = occurrence.getStartTime() - simulationSavedTime;
- long adjustedEndTime = occurrence.getEndTime() - simulationSavedTime;
+ long adjustedStartTime = occurrence.getStartTime() - blindedSavedTime;
+ long adjustedEndTime = occurrence.getEndTime() - blindedSavedTime;
+ if (occurrence.getExecutionTime() < 0) {
+ throw new RuntimeException("executionTime cannot be under zero");
+ }
+ if (adjustedEndTime < adjustedStartTime) {
+ throw new RuntimeException("adjustedEndTime should not be lesser than adjustedStartTime");
+ }
+ if (inputHasCachedTime.containsKey(occurrence.getParametersSerialised()) &&
+ adjustedStartTime - inputHasCachedTime.get(occurrence.getParametersSerialised()) > ttl) {
+ inputHasCachedTime.remove(occurrence.getParametersSerialised());
+ }
if (inputHasCachedTime.containsKey(occurrence.getParametersSerialised())) {
- if (adjustedStartTime - inputHasCachedTime.get(occurrence.getParametersSerialised()) > ttl) {
- inputHasCachedTime.remove(occurrence.getParametersSerialised());
- }
if (Configuration.getStaleness().equals("shrink")) {
if (Objects.deepEquals(inputHasOutput.get(occurrence.getParametersSerialised()), occurrence.getReturnValue())) {
realSavedTime += occurrence.getExecutionTime();
@@ -95,21 +81,19 @@ public class Simulator {
stales++;
}
}
- simulationSavedTime += occurrence.getExecutionTime();
+ blindedSavedTime += occurrence.getExecutionTime();
hits++;
} else {
inputHasCachedTime.put(occurrence.getParametersSerialised(), adjustedEndTime);
if (Configuration.getStaleness().equals("shrink")) {
inputHasOutput.put(occurrence.getParametersSerialised(), occurrence.getReturnValue());
}
+ computationTime += occurrence.getExecutionTime();
timeInCache += ttl;
}
}
- if (Configuration.getStaleness().equals("shrink")) {
- metrics.keepBestMetrics(ttl, hits, timeInCache, stales, realSavedTime);
- } else {
- metrics.keepBestMetrics(ttl, hits, timeInCache, stales, simulationSavedTime);
- }
+ Metrics metrics = new Metrics(ttl, hits, timeInCache, computationTime, stales, Configuration.getStaleness().equals("shrink") ? realSavedTime : blindedSavedTime);
+ pareto.addIfPareto(metrics);
}
public static Stream<Long> generateTTLsOfInterest(Stream<Occurrence> occurrences) {
@@ -118,8 +102,8 @@ public class Simulator {
public static Stream<Long> generateTTLsOfInterest(List<Occurrence> occurrences) {
List<Long> windows = new ArrayList<>();
- for (int i = 1; i < occurrences.size(); i++) {
- long window = occurrences.get(i).getStartTime() - occurrences.get(i - 1).getEndTime();
+ for (int hits = 1; hits < occurrences.size(); hits++) {
+ long window = occurrences.get(hits).getStartTime() - occurrences.get(hits - 1).getEndTime();
if (window > 0) {
windows.add(window);
}
@@ -151,38 +135,36 @@ public class Simulator {
}
private static void testKernels(List<Occurrence> occurrences) {
- Metrics optimisedMetrics = new Metrics();
+ Pareto optimisedPareto = new Pareto();
+ Pareto exhaustivePareto = new Pareto();
Map<String, List<Occurrence>> inputHasOccurrences = Method.groupByInput(occurrences);
Set<Long> ttlsOfInterest = inputHasOccurrences.values().stream()
.map(Simulator::generateTTLsOfInterest)
.reduce(Stream::concat)
- .get()
+ .orElse(Stream.empty())
.collect(Collectors.toSet());
- simulate(occurrences, ttlsOfInterest.stream(), optimisedMetrics);
- List<Metrics> exhaustiveMetrics = Collections.synchronizedList(new ArrayList<>());
- generateAllTTLs(occurrences).forEach(actualTTL -> {
- Metrics partialMetrics = new Metrics();
- exhaustiveMetrics.add(partialMetrics);
- simulate(occurrences.stream(), actualTTL, partialMetrics);
- });
+ simulate(occurrences, ttlsOfInterest.stream(), optimisedPareto);
+ simulate(occurrences, generateAllTTLs(occurrences), exhaustivePareto);
- Metrics.removeDominatedMetrics(exhaustiveMetrics);
- List<Long> missingTTLs = exhaustiveMetrics.stream().map(metrics -> metrics.getTtl())
+ List<Long> missingTTLs = exhaustivePareto.values().stream().map(Metrics::getTtl)
.filter(ttl -> !ttlsOfInterest.contains(ttl))
.sorted()
.collect(Collectors.toList());
if (!missingTTLs.isEmpty()) {
+ System.out.println("=== " + Configuration.getInput() + " ===");
System.out.println("\tMissing ttls: " + missingTTLs);
}
- Metrics maxExhaustiveMetrics = exhaustiveMetrics.stream().max(Metrics::compareTo).orElse(new Metrics());
- if (maxExhaustiveMetrics.getTtl() != optimisedMetrics.getTtl()) {
+ Metrics maxExhaustiveMetrics = exhaustivePareto.getBestMetrics();
+ Metrics maxOptimisedMetrics = optimisedPareto.getBestMetrics();
+ if (maxExhaustiveMetrics.getTtl() != maxOptimisedMetrics.getTtl()) {
+ System.out.println("=== " + Configuration.getInput() + " ===");
System.out.println("\tDIFFERENT BEST METRICS");
- System.out.println("\tOptimised: " + optimisedMetrics);
+ System.out.println("\tOptimised: " + maxOptimisedMetrics);
System.out.println("\tExhaustive: " + maxExhaustiveMetrics);
- switch (maxExhaustiveMetrics.compareTo(optimisedMetrics)) {
+ switch (maxExhaustiveMetrics.compareTo(maxOptimisedMetrics)) {
case -1:
System.out.println("\tOptimised won");
break;
@@ -196,4 +178,16 @@ public class Simulator {
}
}
+ public Pareto getPareto() {
+ return pareto;
+ }
+
+ public void simulate(List<Occurrence> occurrences) {
+ simulate(occurrences, this.pareto);
+ }
+
+ public void simulate(Stream<Occurrence> occurrences, long ttl) {
+ simulate(occurrences, ttl, this.pareto);
+ }
+
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/tfcache/StorageManager.java b/src/main/java/br/ufrgs/inf/prosoft/tfcache/StorageManager.java
index 9df471f..3d3ab5d 100755
--- a/src/main/java/br/ufrgs/inf/prosoft/tfcache/StorageManager.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/StorageManager.java
@@ -5,7 +5,7 @@ import br.ufrgs.inf.prosoft.tfcache.metadata.Occurrence;
import com.google.gson.*;
import java.io.*;
-import java.util.Iterator;
+import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import java.util.logging.Logger;
@@ -16,60 +16,62 @@ public class StorageManager {
private static JsonObject STORAGE = null;
private static String UUID = null;
- public static Metrics get(String uuid, List<Occurrence> occurrences) {
+ public static void put(String uuid, List<Occurrence> occurrences, Pareto pareto) {
if (occurrences == null || occurrences.isEmpty() || occurrences.size() < 2) {
LOGGER.severe("Wrong list of occurrences provided");
System.exit(1);
}
if (Configuration.getStore() == null) {
- return null;
+ return;
}
if (STORAGE == null) {
load();
}
- if (STORAGE.get(uuid) == null) {
- return null;
- }
- String batchUUID = getBatchUUID(occurrences);
- JsonElement storedMetrics = STORAGE.get(uuid).getAsJsonObject().get("batches").getAsJsonObject().get(batchUUID);
+ String batchUUID = Metrics.getUUID(occurrences.stream());
+ STORAGE.getAsJsonObject(uuid).getAsJsonObject("batches").add(batchUUID, new JsonArray());
+ JsonArray jsonPareto = STORAGE.getAsJsonObject(uuid).getAsJsonObject("batches").getAsJsonArray(batchUUID);
Gson gson = new Gson();
- return gson.fromJson(storedMetrics, Metrics.class);
+ pareto.values().stream().map(gson::toJsonTree).forEach(jsonPareto::add);
}
- public static Metrics computeIfAbsent(List<Occurrence> occurrences, Supplier<Metrics> supplier) {
+ public static Pareto get(String uuid, List<Occurrence> occurrences) {
if (occurrences == null || occurrences.isEmpty() || occurrences.size() < 2) {
LOGGER.severe("Wrong list of occurrences provided");
System.exit(1);
}
if (Configuration.getStore() == null) {
- return supplier.get();
+ return null;
}
if (STORAGE == null) {
load();
}
- String batchUUID = getBatchUUID(occurrences);
- JsonElement storedMetrics = STORAGE.get(UUID).getAsJsonObject().get("batches").getAsJsonObject().get(batchUUID);
- Gson gson = new Gson();
- if (storedMetrics != null) {
- return gson.fromJson(storedMetrics, Metrics.class);
+ if (STORAGE.get(uuid) == null) {
+ return null;
+ }
+ String batchUUID = Metrics.getUUID(occurrences.stream());
+ JsonArray jsonPareto = STORAGE.getAsJsonObject(uuid).getAsJsonObject("batches").getAsJsonArray(batchUUID);
+ if (jsonPareto == null) {
+ return null;
}
- Metrics metrics = supplier.get();
- JsonElement jsonMetrics = gson.toJsonTree(metrics);
- STORAGE.get(UUID).getAsJsonObject().get("batches").getAsJsonObject().add(batchUUID, jsonMetrics);
- return metrics;
+ Gson gson = new Gson();
+ List<Metrics> paretoMetrics = new ArrayList<>();
+ jsonPareto.forEach(jsonElement -> {
+ Metrics metrics = gson.fromJson(jsonElement, Metrics.class);
+ paretoMetrics.add(metrics);
+ }
+ );
+ return new Pareto(paretoMetrics);
}
- private static String getBatchUUID(List<Occurrence> occurrences) {
- StringBuilder uuid = new StringBuilder();
- Iterator<Occurrence> iterator = occurrences.iterator();
- while (iterator.hasNext()) {
- Occurrence occurrence = iterator.next();
- uuid.append(occurrence.getStartTime()).append(":").append(occurrence.getEndTime());
- if (iterator.hasNext()) {
- uuid.append(",");
- }
+ public static Pareto computeIfAbsent(List<Occurrence> occurrences, Supplier<Pareto> supplier) {
+ Pareto pareto = get(UUID, occurrences);
+ if (pareto != null) {
+ return pareto;
}
- return uuid.toString();
+
+ pareto = supplier.get();
+ put(UUID, occurrences, pareto);
+ return pareto;
}
private static JsonObject loadStorage() {
@@ -80,16 +82,16 @@ public class StorageManager {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
try (Writer writer = new FileWriter(Configuration.getStore(), true)) {
gson.toJson(new JsonObject(), writer);
- } catch (IOException ex1) {
+ } catch (IOException ignored) {
}
try {
fileReader = new FileReader(Configuration.getStore());
- } catch (FileNotFoundException ex1) {
+ } catch (FileNotFoundException ignored) {
}
}
JsonParser jsonParser = new JsonParser();
- JsonObject storage = jsonParser.parse(fileReader).getAsJsonObject();
- return storage;
+ assert fileReader != null;
+ return jsonParser.parse(fileReader).getAsJsonObject();
}
public static void load() {
@@ -124,7 +126,7 @@ public class StorageManager {
try (Writer writer = new FileWriter(Configuration.getStore())) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
gson.toJson(storage, writer);
- } catch (IOException ex1) {
+ } catch (IOException ignored) {
}
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/tfcache/TFCache.java b/src/main/java/br/ufrgs/inf/prosoft/tfcache/TFCache.java
index 9aa850d..19873f7 100755
--- a/src/main/java/br/ufrgs/inf/prosoft/tfcache/TFCache.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/TFCache.java
@@ -10,15 +10,16 @@ import br.ufrgs.inf.prosoft.tfcache.metadata.Method;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
+
import java.io.FileWriter;
import java.io.IOException;
+import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
/**
- *
* @author romulo
*/
public class TFCache {
@@ -42,22 +43,25 @@ public class TFCache {
LOGGER.log(Level.INFO, "Removing not reusable from {0} methods", this.methods.size());
this.methods.removeIf(Method::isNotReusable);
LOGGER.log(Level.INFO, "Recommending TTL to {0} methods", this.methods.size());
- this.methods.stream().parallel().forEach(Method::recommendTTL);
+ if (Configuration.getVerbose()) {
+ this.methods.forEach(Method::recommendTTL);
+ } else {
+ this.methods.stream().parallel().forEach(Method::recommendTTL);
+ }
LOGGER.log(Level.INFO, "Removing not recommended from {0}", this.methods.size());
this.methods.removeIf(method -> method.getBestMetrics().getSavedTime() == 0);
LOGGER.log(Level.INFO, "Ranking {0} methods according saved time", this.methods.size());
- this.methods.sort((method1, method2) -> method2.getBestMetrics().getSavedTimePerTimeInCache().compareTo(method1.getBestMetrics().getSavedTimePerTimeInCache()));
+ this.methods.sort((method1, method2) -> Double.compare(method2.getBestMetrics().getSavedTime(), method1.getBestMetrics().getSavedTime()));
LOGGER.log(Level.INFO, "Printing recommendations for {0} methods", this.methods.size());
- this.methods.forEach(method -> {
- System.out.println(method.getName()
- + " Occurrences " + method.getOccurrencesSize()
- + " Inputs " + method.groupsOfOccurrences().count()
- + " TTL " + method.getBestMetrics().getTtl()
- + " STpTiC " + method.getBestMetrics().getSavedTimePerTimeInCache()
- + " Saves " + method.getBestMetrics().getSavedTime()
- + " Hits " + method.getBestMetrics().getHits()
- + " Stales " + method.getBestMetrics().getStales());
- });
+ this.methods.forEach(method -> System.out.println(method.getName()
+ + " Occurrences " + method.getOccurrencesSize()
+ + " Inputs " + method.groupsOfOccurrences().count()
+ + " TTL " + method.getBestMetrics().getTtl()
+ + " Saves " + method.getBestMetrics().getSavedTime()
+ + " Hits " + method.getBestMetrics().getHits()
+ + " Computation " + method.getBestMetrics().getComputationTime()
+ + " TimeInCache " + method.getBestMetrics().getTimeInCache()
+ + " Stales " + method.getBestMetrics().getStales()));
}
private void recommendCacheableInputs() {
@@ -70,14 +74,18 @@ public class TFCache {
LOGGER.log(Level.INFO, "Removing not reusable methods from {0} methods", this.methods.size());
this.methods.removeIf(method -> method.groupsOfOccurrences().count() < 1);
LOGGER.log(Level.INFO, "Recommending TTL to {0} methods", this.methods.size());
- this.methods.stream().parallel().forEach(Method::recommendTTLPerInput);
+ if (Configuration.getVerbose()) {
+ this.methods.forEach(Method::recommendTTLPerInput);
+ } else {
+ this.methods.stream().parallel().forEach(Method::recommendTTLPerInput);
+ }
LOGGER.log(Level.INFO, "Removing not recommended inputs from {0}", this.methods.size());
- this.methods.forEach(Method::removeNotRecommededInputs);
+ this.methods.forEach(Method::removeNotRecommendedInputs);
LOGGER.log(Level.INFO, "Removing not recommended methods from {0}", this.methods.size());
this.methods.removeIf(method -> method.groupsOfOccurrences().count() < 1);
LOGGER.log(Level.INFO, "Ranking {0} methods and inputs according saved time", this.methods.size());
this.methods.forEach(Method::rankRecommendations);
- this.methods.sort((method1, method2) -> method2.getEstimatedSavedTimePerTimeInCache().compareTo(method1.getEstimatedSavedTimePerTimeInCache()));
+ this.methods.sort((method1, method2) -> Double.compare(method2.getEstimatedSavedTime(), method1.getEstimatedSavedTime()));
LOGGER.log(Level.INFO, "Printing recommendations for {0} methods", this.methods.size());
this.methods.forEach(method -> {
if (method.getBestMetrics() != null) {
@@ -85,32 +93,30 @@ public class TFCache {
+ " Occurrences " + method.getOccurrencesSize()
+ " Inputs " + method.groupsOfOccurrences().count()
+ " TTL " + method.getBestMetrics().getTtl()
- + " STpTiC " + method.getBestMetrics().getSavedTimePerTimeInCache()
+ " Saves " + method.getBestMetrics().getSavedTime()
+ " Hits " + method.getBestMetrics().getHits()
+ + " Computation " + method.getBestMetrics().getComputationTime()
+ + " TimeInCache " + method.getBestMetrics().getTimeInCache()
+ " Stales " + method.getBestMetrics().getStales());
} else {
System.out.println(method.getName());
}
if (Configuration.getVerbose()) {
- method.groupsOfOccurrences().forEach(group -> {
- System.out.println("\t" + group.getParameters().hashCode()
- + " Occurrences " + group.getOccurrencesSize()
- + " -> TTL " + group.getTtl()
- + " STpTiC " + group.getSavedTimePerTimeInCache()
- + " Saves " + group.getSavedTime()
- + " Hits " + group.getBestMetrics().getHits()
- + " Stales " + group.getBestMetrics().getHits());
- });
+ method.groupsOfOccurrences().forEach(group -> System.out.println("\t" + group.getParameters().hashCode()
+ + " Occurrences " + group.getOccurrencesSize()
+ + " -> TTL " + group.getTtl()
+ + " Saves " + group.getSavedTime()
+ + " Hits " + group.getBestMetrics().getHits()
+ + " Computation " + group.getBestMetrics().getComputationTime()
+ + " TimeInCache " + group.getBestMetrics().getTimeInCache()
+ + " Stales " + group.getBestMetrics().getHits()));
}
});
try (FileWriter fileWriter = new FileWriter(Configuration.getOutput())) {
JsonObject jsonCacheableParameters = new JsonObject();
this.methods.forEach(method -> {
JsonObject cacheableParameters = new JsonObject();
- method.groupsOfOccurrences().forEach(group -> {
- cacheableParameters.addProperty(group.getParameters(), group.getTtl());
- });
+ method.groupsOfOccurrences().forEach(group -> cacheableParameters.addProperty(group.getParameters(), group.getTtl()));
jsonCacheableParameters.add(method.getName(), cacheableParameters);
});
Gson gson = new GsonBuilder().setPrettyPrinting().create();
@@ -121,6 +127,9 @@ public class TFCache {
}
public void recommend() {
+ if (Configuration.getVerbose()) {
+ Configuration.setInput(Arrays.stream(Configuration.getInput().split("/")).reduce((a, b) -> b).orElse(""));
+ }
if (Configuration.getLevel().equals("method")) {
recommendCacheableMethods();
} else {