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 7e785df..d9b4f9c 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
@@ -14,8 +14,6 @@ import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
@@ -33,7 +31,7 @@ public class APLCache<V> {
private static final Logger LOGGER = Logger.getLogger(APLCache.class.getName());
private static String APLCACHE_CACHEABLE_PARAMETERS = System.getenv("APLCACHE_CACHEABLE_PARAMETERS");
- private static final Map<String, Collection<String>> APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS = new HashMap<>();
+ 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;
@@ -55,11 +53,17 @@ public class APLCache<V> {
JsonParser jsonParser = new JsonParser();
JsonObject jsonObject = jsonParser.parse(fileReader).getAsJsonObject();
jsonObject.entrySet().forEach(entry -> {
- Collection<String> parameters = new ArrayList<>();
- entry.getValue().getAsJsonArray().forEach(parameter -> {
- parameters.add(parameter.getAsString());
- });
- APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS.put(entry.getKey(), parameters);
+ Map<String, Long> inputsHasTTL = new HashMap<>();
+ if (entry.getValue().isJsonArray()) {
+ entry.getValue().getAsJsonArray().forEach(parameter -> {
+ inputsHasTTL.put(parameter.getAsString(), 0L);
+ });
+ } 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");
} catch (FileNotFoundException ex) {
@@ -96,14 +100,14 @@ public class APLCache<V> {
LOGGER.log(Level.WARNING, "no method is cacheable");
return false;
}
- Collection<String> cacheableParameters = APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS.get(method);
- if (cacheableParameters == null) {
+ Map<String, Long> cacheableInputsHasTTL = APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS.get(method);
+ if (cacheableInputsHasTTL == null) {
LOGGER.log(Level.WARNING, "method not cacheable: {0}", method);
return false;
}
String serialisedParameters = Stream.of(parameters).map(JSONSerialiser::serialise)
.collect(Collectors.joining(",", "[", "]"));
- if (cacheableParameters.contains(serialisedParameters)) {
+ if (cacheableInputsHasTTL.containsKey(serialisedParameters)) {
return true;
}
log(this.multiCache.getCachePerformance().getName() + " : " + serialisedParameters);
@@ -116,18 +120,32 @@ public class APLCache<V> {
LOGGER.log(Level.WARNING, "no method is cacheable");
return false;
}
- Collection<String> cacheableParameters = APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS.get(method);
+ 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.contains(parameters)) {
+ if (cacheableParameters.containsKey(parameters)) {
return true;
}
log(this.multiCache.getCachePerformance().getName() + " : " + parameters);
return false;
}
+ public long getTTLforInput(String method, String input) {
+ loadCacheableParameters();
+ if (APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS.isEmpty()) {
+ LOGGER.log(Level.WARNING, "no method is cacheable");
+ return 0;
+ }
+ Map<String, Long> cacheableInputsHasTTL = APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS.get(method);
+ if (cacheableInputsHasTTL == null) {
+ LOGGER.log(Level.WARNING, "method not cacheable: {0}", method);
+ return 0;
+ }
+ return cacheableInputsHasTTL.get(input);
+ }
+
public V computeIfAbsent(Thread currentThread, Object[] parameters, Supplier<V> supplier, long timeToLive) {
StackTraceElement[] stackTrace = currentThread.getStackTrace();
StackTraceElement stackTraceElement;
@@ -146,7 +164,13 @@ public class APLCache<V> {
} catch (KeyNotFoundException ex) {
V get = supplier.get();
if (isCacheable(methodName, serialisedParameters)) {
- this.multiCache.put(serialisedParameters, get, timeToLive);
+ long recommendedTTLforInput = getTTLforInput(methodName, serialisedParameters);
+ if (recommendedTTLforInput == 0) {
+ this.multiCache.put(serialisedParameters, get, timeToLive);
+ } else {
+ LOGGER.log(Level.WARNING, "provided TTL being replaced for recommemded");
+ this.multiCache.put(serialisedParameters, get, recommendedTTLforInput);
+ }
}
return get;
}
@@ -171,7 +195,12 @@ public class APLCache<V> {
} catch (KeyNotFoundException ex) {
V get = supplier.get();
if (isCacheable(methodName, serialisedParameters)) {
- this.multiCache.put(serialisedParameters, get);
+ long ttLforInput = getTTLforInput(methodName, serialisedParameters);
+ if (ttLforInput == 0) {
+ this.multiCache.put(serialisedParameters, get);
+ } else {
+ this.multiCache.put(serialisedParameters, get, ttLforInput);
+ }
}
return get;
}