Details
diff --git a/src/main/java/br/ufrgs/inf/prosoft/memoizeittf/adapter/Thresholds.java b/src/main/java/br/ufrgs/inf/prosoft/memoizeittf/adapter/Thresholds.java
index c6fbf67..170fa69 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/memoizeittf/adapter/Thresholds.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/memoizeittf/adapter/Thresholds.java
@@ -1,74 +1,52 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
package br.ufrgs.inf.prosoft.memoizeittf.adapter;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.math.MathContext;
import java.util.ArrayList;
import java.util.List;
-/**
- *
- * @author romulo
- */
public class Thresholds {
- private static final List<BigDecimal> SAVED_TIME_PER_TIME_IN_CACHE = new ArrayList<>();
- private static final BigDecimal SAVED_TIME_PER_TIME_IN_CACHE_THRESHOLD = new BigDecimal(0.5);
-
- private static BigDecimal averageSavedTimePerTimeInCache;
- private static BigDecimal stdDevSavedTimePerTimeInCache;
-
- public static void reset() {
- Thresholds.SAVED_TIME_PER_TIME_IN_CACHE.clear();
- Thresholds.averageSavedTimePerTimeInCache = null;
- Thresholds.stdDevSavedTimePerTimeInCache = null;
- }
-
- public static BigDecimal getAverageSavedTimePerTimeInCache() {
- if (averageSavedTimePerTimeInCache != null) {
- return averageSavedTimePerTimeInCache;
- }
- if (SAVED_TIME_PER_TIME_IN_CACHE.isEmpty()) {
- return new BigDecimal(BigInteger.ZERO);
- }
- averageSavedTimePerTimeInCache = SAVED_TIME_PER_TIME_IN_CACHE.stream().reduce(BigDecimal::add).orElse(new BigDecimal(BigInteger.ZERO))
- .divide(new BigDecimal(SAVED_TIME_PER_TIME_IN_CACHE.size()), MathContext.DECIMAL128);
- return averageSavedTimePerTimeInCache;
- }
-
- public static BigDecimal getStdDevSavedTimePerTimeInCache() {
- if (stdDevSavedTimePerTimeInCache != null) {
- return stdDevSavedTimePerTimeInCache;
- }
- if (SAVED_TIME_PER_TIME_IN_CACHE.isEmpty()) {
- return new BigDecimal(BigInteger.ZERO);
- }
- BigDecimal mean = getAverageSavedTimePerTimeInCache();
- BigDecimal temp = SAVED_TIME_PER_TIME_IN_CACHE.stream()
- .map(frequency -> frequency.subtract(mean).multiply(frequency.subtract(mean)))
- .reduce(BigDecimal::add)
- .orElse(new BigDecimal(BigInteger.ZERO));
- stdDevSavedTimePerTimeInCache = temp.divide(new BigDecimal(SAVED_TIME_PER_TIME_IN_CACHE.size()), MathContext.DECIMAL128).sqrt(MathContext.DECIMAL128);
- return stdDevSavedTimePerTimeInCache;
- }
-
- public static BigDecimal savedTimePerTimeInCacheThreshold(int kStdDev) {
- return getAverageSavedTimePerTimeInCache().add(getStdDevSavedTimePerTimeInCache().multiply(new BigDecimal(kStdDev)));
- }
-
- public static BigDecimal savedTimePerTimeInCacheThreshold() {
- return SAVED_TIME_PER_TIME_IN_CACHE_THRESHOLD;
- }
-
- public static void add(BigDecimal savedTimePerTimeInCache) {
- SAVED_TIME_PER_TIME_IN_CACHE.add(savedTimePerTimeInCache);
- Thresholds.averageSavedTimePerTimeInCache = null;
- Thresholds.stdDevSavedTimePerTimeInCache = null;
- }
+ private static final List<Double> DISTANCES = new ArrayList<>();
+ public static long population;
+ private static Double averageDistance;
+ private static Double stdDevDistance;
+
+ public static void reset() {
+ Thresholds.DISTANCES.clear();
+ Thresholds.averageDistance = null;
+ Thresholds.stdDevDistance = null;
+ }
+
+ public static void addDistance(Double distance) {
+ DISTANCES.add(distance);
+ Thresholds.averageDistance = null;
+ Thresholds.stdDevDistance = null;
+ }
+
+ public static double getAverageDistance() {
+ if (DISTANCES.isEmpty()) return 0D;
+ if (averageDistance == null) averageDistance = DISTANCES.stream().reduce(Double::sum).orElse(0D) / DISTANCES.size();
+ return averageDistance;
+ }
+
+ public static double getStdDevDistance() {
+ if (population == 0) return 0;
+ if (stdDevDistance != null) return stdDevDistance;
+
+ double mean = getAverageDistance();
+ double temp = DISTANCES.stream()
+ .map(difference -> (difference - mean) * (difference - mean))
+ .reduce(Double::sum)
+ .orElse(0D);
+ stdDevDistance = Math.sqrt(temp / population);
+ return stdDevDistance;
+ }
+
+ public static double distanceThreshold(int kStdDev) {
+ return getAverageDistance() - (kStdDev * getStdDevDistance());
+ }
+
+ public static double distanceThreshold() {
+ return 0.5;
+ }
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/memoizeittf/Main.java b/src/main/java/br/ufrgs/inf/prosoft/memoizeittf/Main.java
index 9e7e9b9..5837632 100755
--- a/src/main/java/br/ufrgs/inf/prosoft/memoizeittf/Main.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/memoizeittf/Main.java
@@ -1,8 +1,3 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
package br.ufrgs.inf.prosoft.memoizeittf;
import br.ufrgs.inf.prosoft.memoizeit.adapter.CallGraphReader;
@@ -14,76 +9,85 @@ import br.ufrgs.inf.prosoft.tfcache.configuration.Arguments;
import br.ufrgs.inf.prosoft.tfcache.configuration.Configuration;
import br.ufrgs.inf.prosoft.trace.Trace;
import br.ufrgs.inf.prosoft.trace.reader.Mode;
+
+import java.text.MessageFormat;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
-import java.util.logging.Level;
import java.util.logging.Logger;
-/**
- *
- * @author romulo
- */
public class Main {
- private static final Logger LOGGER = Logger.getLogger(Main.class.getName());
+ private static final Logger LOGGER = Logger.getLogger(Main.class.getName());
+
+ public static void main(String[] args) {
+ System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tF %1$tT+%1$tL] [%4$-7s] [MemoizeItTF] %5$s %n");
- public static void main(String[] args) {
- System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tF %1$tT+%1$tL] [%4$-7s] [MemoizeItTF] %5$s %n");
+ if (args.length < 2) {
+ System.err.println("--trace=<TracePath>" +
+ " --callgraph=<CallGraphPath>" +
+ " [--tfstore=<storePath>]" +
+ " [--tfkernel=<exhaustive|optimised>]" +
+ " [--mode=<complete|hashed|partial>]" +
+ " [--kernel=<iterative|exhaustive>]" +
+ " [--objetive=(savedTime)0..1,0..1(idleTime)]" +
+ " [--window=<windowSize>]" +
+ " [--shift=<shiftTime>]");
+ System.exit(1);
+ }
- if (args.length < 2) {
- System.err.println("--trace=<TracePath> --callgraph=<CallGraphPath> [--tfstore=<storePath>] [--tfkernel=<exhaustive|optimised>] [--mode=<complete|hashed|partial>] [--kernel=<iterative|exhaustive>] [--window=<windowSize>] [--shift=<shiftTime>]");
- System.exit(1);
- }
+ Map<String, String> arguments = Arguments.parse(args);
- Map<String, String> arguments = Arguments.parse(args);
+ 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.info(MessageFormat.format("Using default mode: {0}", mode));
+ }
+ String kernel = arguments.get("kernel");
+ if (kernel == null) {
+ kernel = "exhaustive";
+ LOGGER.info(MessageFormat.format("Using default kernel: {0}", kernel));
+ }
- 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);
- }
+ Long window = null;
+ try {
+ window = Long.valueOf(arguments.get("window"));
+ } catch (NumberFormatException ignored) {
+ }
+ Long shift = null;
+ try {
+ shift = Long.valueOf(arguments.get("shift"));
+ } catch (NumberFormatException ignored) {
+ }
- Long window = null;
- try {
- window = Long.valueOf(arguments.get("window"));
- } catch (NumberFormatException ex) {
- }
- Long shift = null;
- try {
- shift = Long.valueOf(arguments.get("shift"));
- } catch (NumberFormatException ex) {
- }
+ LOGGER.info("Reading callgraph");
+ Graph<String> graph = CallGraphReader.parseFile(callGraphPath);
+ LOGGER.info("Reading traces");
+ List<Trace> traces = TraceReader.parseFile(tracePath, Mode.valueOf(mode.toUpperCase()), window, shift);
+ LOGGER.info(MessageFormat.format("Grouping {0} traces by methods", traces.size()));
+ List<Method> methods = TraceReader.groupByMethods(traces);
+ LOGGER.info(MessageFormat.format("grouped traces into {0} methods", methods.size()));
- LOGGER.log(Level.INFO, "Reading callgraph");
- Graph<String> graph = CallGraphReader.parseFile(callGraphPath);
- LOGGER.log(Level.INFO, "Reading traces");
- List<Trace> traces = TraceReader.parseFile(tracePath, Mode.valueOf(mode.toUpperCase()), window, shift);
- LOGGER.log(Level.INFO, "Grouping {0} traces by methods", traces.size());
- List<Method> methods = TraceReader.groupByMethods(traces);
- LOGGER.log(Level.INFO, "grouped traces into {0} methods", methods.size());
+ Configuration.setLevel("method");
+ Configuration.setKernel(arguments.get("tfkernel"));
+ Configuration.setStaleness("ignore");
+ Configuration.setStore(arguments.get("tfstore"));
+ Configuration.setInput(Arrays.stream(tracePath.split("/")).reduce((a, b) -> b).orElse(""));
+ Configuration.setPreferences(arguments.get("objective"));
+ StorageManager.load();
+ MemoizeItTF memoizeItTF = new MemoizeItTF(methods, graph);
+ memoizeItTF.recommend(kernel.equals("iterative"));
+ StorageManager.update();
+ }
- Configuration.setLevel("method");
- Configuration.setKernel(arguments.get("tfkernel"));
- Configuration.setStaleness("ignore");
- Configuration.setStore(arguments.get("tfstore"));
- StorageManager.load();
- MemoizeItTF memoizeItTF = new MemoizeItTF(methods, graph);
- memoizeItTF.recommend(kernel.equals("iterative"));
- StorageManager.update();
- }
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/memoizeittf/MemoizeItTF.java b/src/main/java/br/ufrgs/inf/prosoft/memoizeittf/MemoizeItTF.java
index ad9a454..d6a09e6 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/memoizeittf/MemoizeItTF.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/memoizeittf/MemoizeItTF.java
@@ -5,68 +5,70 @@ import br.ufrgs.inf.prosoft.memoizeit.graph.Graph;
import br.ufrgs.inf.prosoft.memoizeittf.adapter.Thresholds;
import br.ufrgs.inf.prosoft.memoizeittf.facade.Method;
import br.ufrgs.inf.prosoft.memoizeittf.utils.Methods;
+
+import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
-import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
public class MemoizeItTF extends MemoizeIt {
- private static final Logger LOGGER = Logger.getLogger(MemoizeItTF.class.getName());
-
- private Methods methods;
+ public static final int K_STANDARD_DEVIATION = 0;
+ private static final Logger LOGGER = Logger.getLogger(MemoizeItTF.class.getName());
+ private final Methods methods;
- public MemoizeItTF(List<Method> methods) {
- this(methods, new Graph<String>());
- }
+ public MemoizeItTF(List<Method> methods) {
+ this(methods, new Graph<String>());
+ }
- public MemoizeItTF(List<Method> methods, Graph<String> callgraph) {
- this.methods = new Methods(methods);
- setMethods(this.methods.getMemoizeitMethods());
- setCallGraph(callgraph);
- setMinimumHitRatio(0D);
- }
+ public MemoizeItTF(List<Method> methods, Graph<String> callgraph) {
+ this.methods = new Methods(methods);
+ setMethods(this.methods.getMemoizeitMethods());
+ setCallGraph(callgraph);
+ setMinimumHitRatio(0D);
+ }
- public void recommend() {
- recommend(false);
- }
+ public void recommend() {
+ recommend(false);
+ }
- public void recommend(boolean iteratively) {
- removeChangefulMethods(iteratively);
+ public void recommend(boolean iteratively) {
+ removeChangeableMethods(iteratively);
- this.methods.synchronize();
- List<br.ufrgs.inf.prosoft.tfcache.metadata.Method> tfcacheMethods = this.methods.getTfcacheMethods();
+ this.methods.synchronize();
+ List<br.ufrgs.inf.prosoft.tfcache.metadata.Method> tfCacheMethods = this.methods.getTfcacheMethods();
- LOGGER.log(Level.INFO, "Removing not reusable from {0} methods", tfcacheMethods.size());
- tfcacheMethods.removeIf(br.ufrgs.inf.prosoft.tfcache.metadata.Method::isNotReusable);
- LOGGER.log(Level.INFO, "Recommending TTL to {0} methods", tfcacheMethods.size());
- tfcacheMethods.stream().parallel().forEach(br.ufrgs.inf.prosoft.tfcache.metadata.Method::recommendTTL);
- LOGGER.log(Level.INFO, "Removing not recommended from {0}", tfcacheMethods.size());
- tfcacheMethods.removeIf(method -> method.getBestMetrics().getSavedTime() == 0);
+ LOGGER.info(MessageFormat.format("Removing not reusable from {0} methods", tfCacheMethods.size()));
+ tfCacheMethods.removeIf(it -> it.isNotReusable());
+ LOGGER.info(MessageFormat.format("Recommending TTL to {0} methods", tfCacheMethods.size()));
+ tfCacheMethods.stream().parallel().forEach(it -> it.recommendTTL());
+ LOGGER.info(MessageFormat.format("Removing not recommended from {0}", tfCacheMethods.size()));
+ tfCacheMethods.removeIf(method -> method.getBestMetrics().getSavedTime() == 0);
- LOGGER.log(Level.INFO, "Removing methods according to the STpTiC Threshold from {0}", tfcacheMethods.size());
- tfcacheMethods.removeIf(method -> method.getBestMetrics().getSavedTimePerTimeInCache().compareTo(Thresholds.savedTimePerTimeInCacheThreshold()) < 0);
+ LOGGER.info(MessageFormat.format("Removing methods according to the Threshold from {0}", tfCacheMethods.size()));
+ tfCacheMethods.removeIf(method -> method.getMinEuclideanDistance() > Thresholds.distanceThreshold());
- LOGGER.log(Level.INFO, "Ranking {0} methods according STpTiC", tfcacheMethods.size());
- tfcacheMethods.sort((method1, method2) -> method2.getBestMetrics().getSavedTimePerTimeInCache().compareTo(method1.getBestMetrics().getSavedTimePerTimeInCache()));
+ LOGGER.info(MessageFormat.format("Ranking {0} methods according saved time", tfCacheMethods.size()));
+ tfCacheMethods.sort((method1, method2) -> Double.compare(method2.getEstimatedSavedTime(), method1.getEstimatedSavedTime()));
- LOGGER.log(Level.INFO, "Printing recommendations for {0} methods", tfcacheMethods.size());
- this.methods.synchronize();
- Map<String, br.ufrgs.inf.prosoft.memoizeit.Method> memoizeItMethods = this.methods.getMemoizeitMethods().stream()
- .collect(Collectors.toMap(key -> key.getName(), value -> value));
+ LOGGER.info(MessageFormat.format("Printing recommendations for {0} methods", tfCacheMethods.size()));
+ this.methods.synchronize();
+ Map<String, br.ufrgs.inf.prosoft.memoizeit.Method> memoizeItMethods = this.methods.getMemoizeitMethods().stream()
+ .collect(Collectors.toMap(key -> key.getName(), value -> value));
- tfcacheMethods.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());
- suggestImplementation(memoizeItMethods.get(method.getName()));
- });
- }
+ tfCacheMethods.forEach(method -> {
+ System.out.println(method.getName()
+ + " Occurrences " + method.occurrences().count()
+ + " 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());
+ suggestImplementation(memoizeItMethods.get(method.getName()));
+ });
+ }
}