diff --git a/src/main/java/br/ufrgs/inf/prosoft/aplcache/caching/APLCache.java b/src/main/java/br/ufrgs/inf/prosoft/aplcache/caching/APLCache.java
index d67d5a6..0ffa816 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/aplcache/caching/APLCache.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/aplcache/caching/APLCache.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.aplcache.caching;
import br.ufrgs.inf.prosoft.cache.Caffeine;
@@ -25,9 +20,10 @@ import java.util.stream.Stream;
public class APLCache<V> {
private static final Logger LOGGER = Logger.getLogger(APLCache.class.getName());
- private static final Map<String, Map<String, Long>> APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS = new HashMap<>();
+
private static final String APLCACHE_LOG = System.getenv("APLCACHE_LOG") != null && !System.getenv("APLCACHE_LOG").isEmpty() && !System.getenv("APLCACHE_LOG").equals("null")
? System.getenv("APLCACHE_LOG") : null;
+ private static final Map<String, Map<String, Long>> APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS = new HashMap<>();
private static String APLCACHE_CACHEABLE_PARAMETERS = System.getenv("APLCACHE_CACHEABLE_PARAMETERS");
private final Caffeine<String, V> caffeine;
@@ -47,7 +43,7 @@ public class APLCache<V> {
this.caffeine = new Caffeine<>(name, ttl);
}
- private synchronized static void loadCacheableParameters() {
+ private synchronized static void loadCacheableInputs() {
if (APLCACHE_CACHEABLE_PARAMETERS == null) return;
try (FileReader fileReader = new FileReader(APLCACHE_CACHEABLE_PARAMETERS)) {
JsonParser jsonParser = new JsonParser();
@@ -58,46 +54,23 @@ public class APLCache<V> {
else entry.getValue().getAsJsonObject().entrySet().forEach(innerEntry -> inputsHasTTL.put(innerEntry.getKey(), innerEntry.getValue().getAsLong()));
APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS.put(entry.getKey(), inputsHasTTL);
});
- LOGGER.log(Level.INFO, "cache file loaded");
+ LOGGER.log(Level.INFO, "cacheable inputs file loaded");
} catch (IOException ex) {
- LOGGER.log(Level.SEVERE, "invalid cache file");
+ LOGGER.log(Level.SEVERE, "invalid cacheable inputs file");
}
APLCACHE_CACHEABLE_PARAMETERS = null;
}
private static void log(String message) {
- if (APLCACHE_LOG == null) {
- return;
- }
+ if (APLCACHE_LOG == null) return;
try (FileWriter fileWriter = new FileWriter(APLCACHE_LOG, true)) {
fileWriter.write(message + "\n");
- } catch (IOException ex) {
- }
- }
-
- public boolean isCacheable(Thread currentThread, Object... parameters) {
- StackTraceElement[] stackTrace = currentThread.getStackTrace();
- StackTraceElement stackTraceElement;
- try {
- stackTraceElement = stackTrace[2];
- } catch (ArrayIndexOutOfBoundsException ex) {
- stackTraceElement = stackTrace[0];
- }
- return isCacheable(stackTraceElement, parameters);
- }
-
- public boolean isCacheable(StackTraceElement stackTraceElement, Object... parameters) {
- try {
- String methodName = stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName();
- methodName = methodName.replace("$", ".");
- return isCacheable(methodName, parameters);
- } catch (Exception ex) {
- return false;
+ } catch (IOException ignored) {
}
}
- public boolean isCacheable(String method, Object... parameters) {
- loadCacheableParameters();
+ public boolean isCacheable(String method, String serialisedParameters) {
+ loadCacheableInputs();
if (APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS.isEmpty()) {
LOGGER.log(Level.WARNING, "no method is cacheable");
return false;
@@ -107,35 +80,14 @@ public class APLCache<V> {
LOGGER.log(Level.WARNING, "method not cacheable: {0}", method);
return false;
}
- String serialisedParameters = Stream.of(parameters).map(JSONSerialiser::serialise)
- .collect(Collectors.joining(",", "[", "]"));
- if (cacheableInputsHasTTL.containsKey(serialisedParameters)) {
- return true;
- }
+ if (cacheableInputsHasTTL.containsKey(serialisedParameters)) return true;
log(this.caffeine.getCachePerformance().getName() + " : " + serialisedParameters);
return false;
}
- public boolean isCacheable(String method, String parameters) {
- loadCacheableParameters();
- if (APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS.isEmpty()) {
- LOGGER.log(Level.WARNING, "no method is cacheable");
- return false;
- }
- Map<String, Long> cacheableParameters = APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS.get(method);
- if (cacheableParameters == null) {
- LOGGER.log(Level.WARNING, "method not cacheable: {0}", method);
- return false;
- }
- if (cacheableParameters.containsKey(parameters)) {
- return true;
- }
- log(this.caffeine.getCachePerformance().getName() + " : " + parameters);
- return false;
- }
-
+ @Deprecated
public long getTTLforInput(String method, String input) {
- loadCacheableParameters();
+ loadCacheableInputs();
if (APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS.isEmpty()) {
LOGGER.log(Level.WARNING, "no method is cacheable");
return 0;
@@ -145,65 +97,43 @@ public class APLCache<V> {
LOGGER.log(Level.WARNING, "method not cacheable: {0}", method);
return 0;
}
- return cacheableInputsHasTTL.get(input);
+ Long recommendedTTL = cacheableInputsHasTTL.get(input);
+ if (recommendedTTL == null) return 0;
+ return recommendedTTL;
}
public V computeIfAbsent(Thread currentThread, Object[] parameters, Supplier<V> supplier, long timeToLive) {
- StackTraceElement[] stackTrace = currentThread.getStackTrace();
- StackTraceElement stackTraceElement;
- try {
- stackTraceElement = stackTrace[2];
- } catch (ArrayIndexOutOfBoundsException ex) {
- stackTraceElement = stackTrace[0];
- }
- String methodName = stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName();
- methodName = methodName.replace("$", ".");
-
- String serialisedParameters = Stream.of(parameters).map(JSONSerialiser::serialise)
- .collect(Collectors.joining(",", "[", "]"));
- synchronized (serialisedParameters) {
- try {
- return this.caffeine.get(serialisedParameters);
- } catch (KeyNotFoundException ex) {
- V get = supplier.get();
- if (isCacheable(methodName, serialisedParameters)) {
- long recommendedTTLforInput = getTTLforInput(methodName, serialisedParameters);
- if (recommendedTTLforInput == 0) this.caffeine.put(serialisedParameters, get, timeToLive);
- else this.caffeine.put(serialisedParameters, get, recommendedTTLforInput);
- }
- return get;
- }
- }
+ return computeIfAbsent(currentThread.getStackTrace()[2], parameters, supplier, timeToLive);
}
public V computeIfAbsent(Thread currentThread, Object[] parameters, Supplier<V> supplier) {
- StackTraceElement[] stackTrace = currentThread.getStackTrace();
- StackTraceElement stackTraceElement;
- try {
- stackTraceElement = stackTrace[2];
- } catch (ArrayIndexOutOfBoundsException ex) {
- stackTraceElement = stackTrace[0];
- }
+ return computeIfAbsent(currentThread.getStackTrace()[2], parameters, supplier, 0);
+ }
+
+ public V computeIfAbsent(StackTraceElement stackTraceElement, Object[] parameters, Supplier<V> supplier, long timeToLive) {
String methodName = stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName();
methodName = methodName.replace("$", ".");
+ return computeIfAbsent(methodName, parameters, supplier, timeToLive);
+ }
- String serialisedParameters = Stream.of(parameters).map(JSONSerialiser::serialise)
- .collect(Collectors.joining(",", "[", "]"));
+ public V computeIfAbsent(String methodName, Object[] parameters, Supplier<V> supplier) {
+ return computeIfAbsent(methodName, parameters, supplier, 0);
+ }
+
+ public V computeIfAbsent(String methodName, Object[] parameters, Supplier<V> supplier, long timeToLive) {
+ String serialisedParameters = Stream.of(parameters).map(JSONSerialiser::serialise).collect(Collectors.joining(",", "[", "]"));
synchronized (serialisedParameters) {
try {
return this.caffeine.get(serialisedParameters);
} catch (KeyNotFoundException ex) {
V get = supplier.get();
if (isCacheable(methodName, serialisedParameters)) {
- long ttLforInput = getTTLforInput(methodName, serialisedParameters);
- if (ttLforInput == 0) {
- this.caffeine.put(serialisedParameters, get);
- } else {
- this.caffeine.put(serialisedParameters, get, ttLforInput);
- }
+ if (timeToLive != 0) this.caffeine.put(serialisedParameters, get, timeToLive);
+ else this.caffeine.put(serialisedParameters, get);
}
return get;
}
}
}
+
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/aplcache/metadata/Method.java b/src/main/java/br/ufrgs/inf/prosoft/aplcache/metadata/Method.java
index b305a2f..2898ad0 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/aplcache/metadata/Method.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/aplcache/metadata/Method.java
@@ -6,7 +6,6 @@ import java.util.*;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
-import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Method {
@@ -42,9 +41,7 @@ public class Method {
}
public Stream<Occurrence> occurrences() {
- if (this.occurrences == null) {
- throw new RuntimeException("Occurrences already consumed");
- }
+ if (this.occurrences == null) throw new RuntimeException("Occurrences already consumed");
return this.occurrences.stream();
}
@@ -68,9 +65,7 @@ public class Method {
if (TRACER_VERBOSE) {
System.out.print(".");
System.out.flush();
- if (++this.i % 100 == 0) {
- System.out.println();
- }
+ if (++this.i % 100 == 0) System.out.println();
}
String parameters = occurrence.getParametersSerialised();
synchronized (groupByParameter) {
@@ -84,31 +79,25 @@ public class Method {
}
}
});
- this.groupsOfOccurrences = groupByParameter.values().stream().collect(Collectors.toList());
+ this.groupsOfOccurrences = new ArrayList<>(groupByParameter.values());
}
public void removeSingleOccurrences() {
- if (this.groupsOfOccurrences == null) {
- groupByInput();
- }
- int initialCountofOccurrences = this.groupsOfOccurrences.size();
+ if (this.groupsOfOccurrences == null) groupByInput();
+ int initialCountOfOccurrences = this.groupsOfOccurrences.size();
this.groupsOfOccurrences.removeIf(groupOfOccurrences -> groupOfOccurrences.getOccurrencesSize() < 2);
- int removedOccurrences = initialCountofOccurrences - this.groupsOfOccurrences.size();
- if (removedOccurrences > 0) {
- LOGGER.log(Level.INFO, "\tRemoved {0} of {1} inputs from method {2}", new Object[]{removedOccurrences, initialCountofOccurrences, this.name});
- }
+ int removedOccurrences = initialCountOfOccurrences - this.groupsOfOccurrences.size();
+ if (removedOccurrences > 0) LOGGER.log(Level.INFO, "\tRemoved {0} of {1} inputs from method {2}", new Object[]{removedOccurrences, initialCountOfOccurrences, this.name});
}
public void calculateMetrics() {
- if (this.groupsOfOccurrences == null) {
- groupByInput();
- }
- Collections.sort(this.groupsOfOccurrences, Comparator.comparingInt(GroupOfOccurrences::getOccurrencesSize));
+ if (this.groupsOfOccurrences == null) groupByInput();
+ this.groupsOfOccurrences.sort(Comparator.comparingInt(GroupOfOccurrences::getOccurrencesSize));
this.groupsOfOccurrences.stream().parallel().forEach(GroupOfOccurrences::calculateMetrics);
}
public void calculateThresholds() {
- this.groupsOfOccurrences.stream().forEach(GroupOfOccurrences::calculateThresholds);
+ this.groupsOfOccurrences.forEach(GroupOfOccurrences::calculateThresholds);
}
public void filterCacheableInputs() {