Details
diff --git a/src/main/java/br/ufrgs/inf/prosoft/tfcache/configuration/Arguments.java b/src/main/java/br/ufrgs/inf/prosoft/tfcache/configuration/Arguments.java
new file mode 100644
index 0000000..8d7d6bd
--- /dev/null
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/configuration/Arguments.java
@@ -0,0 +1,24 @@
+package br.ufrgs.inf.prosoft.tfcache.configuration;
+
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class Arguments {
+
+ public static Map<String, String> parse(String[] args) {
+ Map<String, String> arguments = Stream.of(args).map(arg -> {
+ arg = arg.replaceFirst("--", "");
+ int indexOf = arg.indexOf("=");
+ if (indexOf == -1) {
+ return new String[]{arg, ""};
+ }
+ return new String[]{arg.substring(0, indexOf), arg.substring(indexOf + 1)};
+ }).collect(Collectors.toMap(array -> {
+ return array[0];
+ }, array -> {
+ return array[1];
+ }));
+ return arguments;
+ }
+}
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 a0f1548..0c689ed 100644
--- 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,16 +1,16 @@
package br.ufrgs.inf.prosoft.tfcache.configuration;
+import com.google.gson.JsonObject;
+import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
-/**
- *
- * @author root
- */
public class Configuration {
private static final Logger LOGGER = Logger.getLogger(Configuration.class.getName());
+ private static String input = null;
+ private static String store = null;
private static String level = "method";
private static String output = null;
private static String changeability = "allow";
@@ -18,13 +18,60 @@ public class Configuration {
private static String kernel = "exhaustive";
private static boolean verbose = false;
+ public static void process(String[] args) {
+ process(Arguments.parse(args));
+ }
+
+ public static void process(Map<String, String> arguments) {
+ setInput(arguments.get("trace"));
+ setStore(arguments.get("store"));
+ setLevel(arguments.get("level"));
+ setOutput(arguments.get("output"));
+ if (getLevel().equals("input") && getOutput() == null) {
+ LOGGER.severe("Output is required for input-level recommendations");
+ System.exit(1);
+ }
+ setChangeability(arguments.get("changeability"));
+ setStaleness(arguments.get("staleness"));
+ setKernel(arguments.get("kernel"));
+ setVerbose(arguments.get("verbose"));
+ }
+
+ public static void setInput(String input) {
+ if (input == null || input.isBlank()) {
+ LOGGER.severe("<TracePath> is required");
+ System.exit(1);
+ }
+ Configuration.input = input;
+ }
+
+ public static String getInput() {
+ return input;
+ }
+
+ public static void setStore(String store) {
+ if (store == null) {
+ LOGGER.info("store disabled");
+ return;
+ }
+ if (store.isBlank()) {
+ LOGGER.severe("storePath cannot be empty");
+ System.exit(1);
+ }
+ Configuration.store = store;
+ }
+
+ public static String getStore() {
+ return store;
+ }
+
public static void setLevel(String level) {
if (level == null) {
LOGGER.log(Level.INFO, "Using default level: {0}", Configuration.level);
return;
}
if (!level.equals("method") && !level.equals("input")) {
- LOGGER.log(Level.SEVERE, "Unrecognised option for level");
+ LOGGER.severe("Unrecognised option for level");
System.exit(1);
}
Configuration.level = level;
@@ -51,7 +98,7 @@ public class Configuration {
return;
}
if (!changeability.equals("allow") && !changeability.equals("deny")) {
- LOGGER.log(Level.SEVERE, "Unrecognised option for changeability");
+ LOGGER.severe("Unrecognised option for changeability");
System.exit(1);
}
Configuration.changeability = changeability;
@@ -67,7 +114,7 @@ public class Configuration {
return;
}
if (!staleness.equals("ignore") && !staleness.equals("shrink")) {
- LOGGER.log(Level.SEVERE, "Unrecognised option for staleness");
+ LOGGER.severe("Unrecognised option for staleness");
System.exit(1);
}
Configuration.staleness = staleness;
@@ -83,7 +130,7 @@ public class Configuration {
return;
}
if (!kernel.equals("exhaustive") && !kernel.equals("optimised") && !kernel.equals("test")) {
- LOGGER.log(Level.SEVERE, "Unrecognised option for kernel");
+ LOGGER.severe("Unrecognised option for kernel");
System.exit(1);
}
Configuration.kernel = kernel;
@@ -98,7 +145,7 @@ public class Configuration {
return;
}
if (!verbose.equals("true") && !verbose.equals("false")) {
- LOGGER.log(Level.SEVERE, "Unrecognised option for verbose");
+ LOGGER.severe("Unrecognised option for verbose");
System.exit(1);
}
Configuration.verbose = verbose.equals("true");
@@ -108,4 +155,18 @@ public class Configuration {
return verbose;
}
+ public static String getUUID() {
+ return "level:" + Configuration.getLevel()
+ + ",staleness:" + Configuration.getStaleness()
+ + ",kernel:" + Configuration.getKernel();
+ }
+
+ public static JsonObject toJSONObject() {
+ JsonObject configuration = new JsonObject();
+ configuration.addProperty("level", Configuration.getLevel());
+ configuration.addProperty("staleness", Configuration.getStaleness());
+ configuration.addProperty("kernel", Configuration.getKernel());
+ return configuration;
+ }
+
}
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 b4e039c..60c0f04 100755
--- a/src/main/java/br/ufrgs/inf/prosoft/tfcache/Main.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/Main.java
@@ -10,11 +10,8 @@ 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.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
/**
*
@@ -28,45 +25,19 @@ 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> [--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] [--verbose=<false|true>]");
System.exit(1);
}
- Map<String, String> arguments = Stream.of(args).map(arg -> {
- arg = arg.replaceFirst("--", "");
- int indexOf = arg.indexOf("=");
- if (indexOf == -1) {
- return new String[]{arg, ""};
- }
- return new String[]{arg.substring(0, indexOf), arg.substring(indexOf + 1)};
- }).collect(Collectors.toMap(array -> {
- return array[0];
- }, array -> {
- return array[1];
- }));
-
- String tracePath = arguments.get("trace");
- if (tracePath == null || tracePath.isBlank()) {
- System.err.println("<TracePath> is required");
- System.exit(1);
- }
-
- Configuration.setLevel(arguments.get("level"));
- Configuration.setOutput(arguments.get("output"));
- if (Configuration.getLevel().equals("input") && Configuration.getOutput() == null) {
- LOGGER.log(Level.SEVERE, "Output is required for input-level recommendations");
- System.exit(1);
- }
- Configuration.setChangeability(arguments.get("changeability"));
- Configuration.setStaleness(arguments.get("staleness"));
- Configuration.setKernel(arguments.get("kernel"));
- Configuration.setVerbose(arguments.get("verbose"));
+ Configuration.process(args);
LOGGER.log(Level.INFO, "Reading traces");
- List<Trace> traces = TraceReader.parseFile(tracePath);
+ List<Trace> traces = TraceReader.parseFile(Configuration.getInput());
LOGGER.log(Level.INFO, "Grouping {0} traces by methods", traces.size());
List<Method> methods = TraceReader.groupByMethods(traces);
+ StorageManager.load();
TFCache tfCache = new TFCache(methods);
tfCache.recommend();
+ StorageManager.update();
}
}
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 49384f3..91bcc9f 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
@@ -7,6 +7,7 @@ package br.ufrgs.inf.prosoft.tfcache.metadata;
import br.ufrgs.inf.prosoft.tfcache.Metrics;
import br.ufrgs.inf.prosoft.tfcache.Simulator;
+import br.ufrgs.inf.prosoft.tfcache.StorageManager;
import br.ufrgs.inf.prosoft.tfcache.configuration.Configuration;
import java.math.BigDecimal;
import java.util.ArrayList;
@@ -53,22 +54,15 @@ public class Method {
}
public Metrics getBestMetrics() {
- if (this.bestMetrics == null) {
- throw new RuntimeException("hitsPerTimeInCache must be calculated");
- }
return this.bestMetrics;
}
- public Long getTtl() {
- return getBestMetrics().getTtl();
- }
-
- public Long getSavedTime() {
- return getBestMetrics().getSavedTime();
- }
-
- public BigDecimal getSavedTimePerTimeInCache() {
- return getBestMetrics().getSavedTimePerTimeInCache();
+ public BigDecimal getEstimatedSavedTimePerTimeInCache() {
+ if (getBestMetrics() != null) {
+ return getBestMetrics().getSavedTimePerTimeInCache();
+ }
+ GroupOfOccurrences max = groupsOfOccurrences().max((group1, group2) -> group1.getSavedTimePerTimeInCache().compareTo(group2.getSavedTimePerTimeInCache())).get();
+ return max.getSavedTimePerTimeInCache();
}
public Stream<Occurrence> occurrences() {
@@ -185,7 +179,7 @@ public class Method {
public void recommendTTL() {
if (this.bestMetrics != null) {
- LOGGER.log(Level.WARNING, "HitsPerTimeInCache already calculated");
+ LOGGER.log(Level.WARNING, "SavedTimePerTimeInCache already calculated");
}
if (this.occurrences == null) {
throw new RuntimeException("groupByInputs called. Cannot proceed");
@@ -207,19 +201,15 @@ public class Method {
System.out.println("=== " + getName() + " ===");
}
groupsOfOccurrences().parallel().forEach(GroupOfOccurrences::calculateHitsPerTimeInCache);
- if (this.bestMetrics == null) {
- long savedTime = groupsOfOccurrences().map(GroupOfOccurrences::getSavedTime).reduce(Long::sum).get();
- long hits = groupsOfOccurrences().map(GroupOfOccurrences::getHits).reduce(Long::sum).get();
- long stales = groupsOfOccurrences().map(GroupOfOccurrences::getStales).reduce(Long::sum).get();
- GroupOfOccurrences max = groupsOfOccurrences().max((group1, group2) -> Long.compare(group1.getSavedTime(), group2.getSavedTime())).get();
- long ttl = max.getTtl();
- BigDecimal hitsPerTimeInCache = max.getSavedTimePerTimeInCache();
- this.bestMetrics = new Metrics(ttl, hits, stales, savedTime, hitsPerTimeInCache);
+ 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;
}
}
public void removeNotRecommededInputs() {
- if (this.groupsOfOccurrences == null || this.bestMetrics == null) {
+ if (this.groupsOfOccurrences == null) {
throw new RuntimeException("Recommendations not called");
}
int initialCountofOccurrences = this.groupsOfOccurrences.size();
@@ -234,7 +224,7 @@ public class Method {
if (this.groupsOfOccurrences == null) {
throw new RuntimeException("groupsOfOccurrences is null");
}
- this.groupsOfOccurrences.sort((group1, group2) -> Long.compare(group2.getSavedTime(), group1.getSavedTime()));
+ this.groupsOfOccurrences.sort((group1, group2) -> group2.getSavedTimePerTimeInCache().compareTo(group1.getSavedTimePerTimeInCache()));
}
@Override
diff --git a/src/main/java/br/ufrgs/inf/prosoft/tfcache/Metrics.java b/src/main/java/br/ufrgs/inf/prosoft/tfcache/Metrics.java
index 4f34d9f..4439e6a 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/tfcache/Metrics.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/Metrics.java
@@ -22,6 +22,7 @@ public class Metrics implements Comparable<Metrics> {
private long ttl;
private long hits;
+ private long timeInCache;
private long stales;
private long savedTime;
private BigDecimal savedTimePerTimeInCache;
@@ -30,12 +31,19 @@ public class Metrics implements Comparable<Metrics> {
this.savedTimePerTimeInCache = new BigDecimal(BigInteger.ZERO);
}
- public Metrics(long ttl, long hits, long stales, long savedTime, BigDecimal hitsPerTimeInCache) {
+ 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");
+ }
+ if (timeInCache == 0) {
+ throw new RuntimeException("timeInCache should not be zero");
+ }
this.ttl = ttl;
this.hits = hits;
+ this.timeInCache = timeInCache;
this.stales = stales;
this.savedTime = savedTime;
- this.savedTimePerTimeInCache = hitsPerTimeInCache;
+ this.savedTimePerTimeInCache = new BigDecimal(this.savedTime).divide(new BigDecimal(this.timeInCache), MathContext.DECIMAL128);
}
public long getTtl() {
@@ -46,6 +54,10 @@ public class Metrics implements Comparable<Metrics> {
return this.hits;
}
+ public long getTimeInCache() {
+ return timeInCache;
+ }
+
public long getStales() {
return this.stales;
}
@@ -58,6 +70,10 @@ public class Metrics implements Comparable<Metrics> {
return this.savedTimePerTimeInCache;
}
+ public synchronized void keepBestMetrics(Metrics metrics) {
+ keepBestMetrics(metrics.ttl, metrics.hits, metrics.timeInCache, metrics.stales, metrics.savedTime);
+ }
+
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
@@ -73,9 +89,10 @@ public class Metrics implements Comparable<Metrics> {
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, stales, savedTime, savedTimePerTimeInCache) == -1) {
+ 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;
@@ -101,14 +118,14 @@ public class Metrics implements Comparable<Metrics> {
@Override
public int compareTo(Metrics other) {
- return compareTo(other.ttl, other.hits, other.stales, other.savedTime, other.savedTimePerTimeInCache);
+ return compareTo(other.ttl, other.hits, other.timeInCache, other.stales, other.savedTime, other.savedTimePerTimeInCache);
}
- private int compareTo(long ttl, long hits, long stales, long savedTime, BigDecimal savedTimePerTimeInCache) {
- if (this.savedTimePerTimeInCache.compareTo(savedTimePerTimeInCache) == 1) {
+ private int compareTo(long ttl, long hits, long timeInCache, long stales, long savedTime, BigDecimal savedTimePerTimeInCache) {
+ if (getSavedTimePerTimeInCache().compareTo(savedTimePerTimeInCache) == 1) {
return 1;
}
- if (this.savedTimePerTimeInCache.compareTo(savedTimePerTimeInCache) == -1) {
+ if (getSavedTimePerTimeInCache().compareTo(savedTimePerTimeInCache) == -1) {
return -1;
}
if (this.stales < stales) {
@@ -135,6 +152,12 @@ public class Metrics implements Comparable<Metrics> {
if (this.ttl > ttl) {
return -1;
}
+ if (this.timeInCache < timeInCache) {
+ return 1;
+ }
+ if (this.timeInCache > timeInCache) {
+ return -1;
+ }
return 0;
}
@@ -156,10 +179,11 @@ public class Metrics implements Comparable<Metrics> {
@Override
public String toString() {
return "TTL: " + this.ttl
- + " STpTiC: " + this.savedTimePerTimeInCache
+ + " STpTiC: " + getSavedTimePerTimeInCache()
+ " Stales: " + this.stales
+ " Hits: " + this.hits
- + " SavedTime: " + this.savedTime;
+ + " SavedTime: " + this.savedTime
+ + " TimeInCache: " + this.timeInCache;
}
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/tfcache/Simulator.java b/src/main/java/br/ufrgs/inf/prosoft/tfcache/Simulator.java
index ed926f7..814d241 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/tfcache/Simulator.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/Simulator.java
@@ -46,17 +46,21 @@ public class Simulator {
}
public static void simulate(List<Occurrence> occurrences, Metrics metrics) {
- switch (Configuration.getKernel()) {
- case "exhaustive":
- simulate(occurrences, generateAllTTLs(occurrences), metrics);
- break;
- case "optimised":
- simulate(occurrences, generateTTLsOfInterest(occurrences), metrics);
- break;
- default:
- testKernels(occurrences);
- break;
- }
+ Metrics computeIfAbsent = StorageManager.computeIfAbsent(occurrences, () -> {
+ switch (Configuration.getKernel()) {
+ case "exhaustive":
+ simulate(occurrences, generateAllTTLs(occurrences), metrics);
+ break;
+ case "optimised":
+ simulate(occurrences, generateTTLsOfInterest(occurrences), metrics);
+ break;
+ default:
+ testKernels(occurrences);
+ break;
+ }
+ return metrics;
+ });
+ metrics.keepBestMetrics(computeIfAbsent);
}
public static void simulate(List<Occurrence> occurrences, Stream<Long> ttls, Metrics metrics) {
diff --git a/src/main/java/br/ufrgs/inf/prosoft/tfcache/StorageManager.java b/src/main/java/br/ufrgs/inf/prosoft/tfcache/StorageManager.java
new file mode 100644
index 0000000..6fb32a5
--- /dev/null
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/StorageManager.java
@@ -0,0 +1,138 @@
+package br.ufrgs.inf.prosoft.tfcache;
+
+import br.ufrgs.inf.prosoft.tfcache.configuration.Configuration;
+import br.ufrgs.inf.prosoft.tfcache.metadata.Occurrence;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Supplier;
+import java.util.logging.Logger;
+
+public class StorageManager {
+
+ private static final Logger LOGGER = Logger.getLogger(StorageManager.class.getName());
+ private static JsonObject STORAGE = null;
+ private static String UUID = null;
+
+ public static Metrics 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 null;
+ }
+ 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);
+ Gson gson = new Gson();
+ return gson.fromJson(storedMetrics, Metrics.class);
+ }
+
+ public static Metrics computeIfAbsent(List<Occurrence> occurrences, Supplier<Metrics> supplier) {
+ 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();
+ }
+ 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);
+ }
+ Metrics metrics = supplier.get();
+ JsonElement jsonMetrics = gson.toJsonTree(metrics);
+ STORAGE.get(UUID).getAsJsonObject().get("batches").getAsJsonObject().add(batchUUID, jsonMetrics);
+ return metrics;
+ }
+
+ 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(",");
+ }
+ }
+ return uuid.toString();
+ }
+
+ private static JsonObject loadStorage() {
+ FileReader fileReader = null;
+ try {
+ fileReader = new FileReader(Configuration.getStore());
+ } catch (FileNotFoundException ex) {
+ Gson gson = new GsonBuilder().setPrettyPrinting().create();
+ try (Writer writer = new FileWriter(Configuration.getStore(), true)) {
+ gson.toJson(new JsonObject(), writer);
+ } catch (IOException ex1) {
+ }
+ try {
+ fileReader = new FileReader(Configuration.getStore());
+ } catch (FileNotFoundException ex1) {
+ }
+ }
+ JsonParser jsonParser = new JsonParser();
+ JsonObject storage = jsonParser.parse(fileReader).getAsJsonObject();
+ return storage;
+ }
+
+ public static void load() {
+ if (Configuration.getStore() == null) {
+ return;
+ }
+ STORAGE = loadStorage();
+ UUID = Configuration.getUUID();
+ if (STORAGE.get(UUID) == null) {
+ LOGGER.info("Configurations not stored yet");
+ STORAGE.add(UUID, new JsonObject());
+ STORAGE.get(UUID).getAsJsonObject().add("configuration", Configuration.toJSONObject());
+ STORAGE.get(UUID).getAsJsonObject().add("batches", new JsonObject());
+ }
+ }
+
+ public static void update() {
+ if (Configuration.getStore() == null) {
+ return;
+ }
+ JsonObject storage = loadStorage();
+ if (storage.get(UUID) == null) {
+ storage.add(UUID, STORAGE.get(UUID));
+ } else {
+ STORAGE.get(UUID).getAsJsonObject().get("batches").getAsJsonObject().entrySet().forEach(entry -> {
+ String computedBatchUUID = entry.getKey();
+ if (storage.get(UUID).getAsJsonObject().get("batches").getAsJsonObject().get(computedBatchUUID) == null) {
+ storage.get(UUID).getAsJsonObject().get("batches").getAsJsonObject().add(computedBatchUUID, entry.getValue());
+ }
+ });
+ }
+ try (Writer writer = new FileWriter(Configuration.getStore())) {
+ Gson gson = new GsonBuilder().setPrettyPrinting().create();
+ gson.toJson(storage, writer);
+ } catch (IOException ex1) {
+ }
+ }
+
+}
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 a74a2e6..9aa850d 100755
--- a/src/main/java/br/ufrgs/inf/prosoft/tfcache/TFCache.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/tfcache/TFCache.java
@@ -44,17 +44,17 @@ public class TFCache {
LOGGER.log(Level.INFO, "Recommending TTL to {0} methods", this.methods.size());
this.methods.stream().parallel().forEach(Method::recommendTTL);
LOGGER.log(Level.INFO, "Removing not recommended from {0}", this.methods.size());
- this.methods.removeIf(method -> method.getSavedTime() == 0);
+ 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) -> Long.compare(method2.getSavedTime(), method1.getSavedTime()));
+ this.methods.sort((method1, method2) -> method2.getBestMetrics().getSavedTimePerTimeInCache().compareTo(method1.getBestMetrics().getSavedTimePerTimeInCache()));
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.getTtl()
- + " STpTiC " + method.getSavedTimePerTimeInCache()
- + " Saves " + method.getSavedTime()
+ + " TTL " + method.getBestMetrics().getTtl()
+ + " STpTiC " + method.getBestMetrics().getSavedTimePerTimeInCache()
+ + " Saves " + method.getBestMetrics().getSavedTime()
+ " Hits " + method.getBestMetrics().getHits()
+ " Stales " + method.getBestMetrics().getStales());
});
@@ -77,17 +77,21 @@ public class TFCache {
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) -> Long.compare(method2.getSavedTime(), method1.getSavedTime()));
+ this.methods.sort((method1, method2) -> method2.getEstimatedSavedTimePerTimeInCache().compareTo(method1.getEstimatedSavedTimePerTimeInCache()));
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.getTtl()
- + " STpTiC " + method.getSavedTimePerTimeInCache()
- + " Saves " + method.getSavedTime()
- + " Hits " + method.getBestMetrics().getHits()
- + " Stales " + method.getBestMetrics().getStales());
+ if (method.getBestMetrics() != null) {
+ 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());
+ } else {
+ System.out.println(method.getName());
+ }
if (Configuration.getVerbose()) {
method.groupsOfOccurrences().forEach(group -> {
System.out.println("\t" + group.getParameters().hashCode()