cache

Details

diff --git a/src/main/java/br/ufrgs/inf/prosoft/cache/Caffeine.java b/src/main/java/br/ufrgs/inf/prosoft/cache/Caffeine.java
index 78fadb0..6e719f6 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/cache/Caffeine.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/cache/Caffeine.java
@@ -5,11 +5,12 @@
  */
 package br.ufrgs.inf.prosoft.cache;
 
+import com.github.benmanes.caffeine.cache.Expiry;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
-import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.BiConsumer;
 import java.util.stream.Collectors;
 
@@ -24,6 +25,7 @@ public class Caffeine<K, V> implements Cache<K, V> {
     private static final boolean CACHE_EVALUATE_PERFORMANCE = System.getenv("CACHE_EVENTS") == null || !System.getenv("CACHE_EVENTS").equals("false");
     private static final boolean CACHE_REGISTER_SIZE = System.getenv("CACHE_REGISTER_SIZE") != null && System.getenv("CACHE_REGISTER_SIZE").equals("true");
     private final com.github.benmanes.caffeine.cache.Cache<Optional<K>, Optional<V>> cache;
+    private final ConcurrentHashMap<Optional<K>, Long> keyHasTTL;
     private final CachePerformance cachePerformance;
 
     public Caffeine() {
@@ -47,32 +49,51 @@ public class Caffeine<K, V> implements Cache<K, V> {
     }
 
     public Caffeine(CachePerformance cachingPerformance) {
-        this.cachePerformance = cachingPerformance;
-        this.cache = com.github.benmanes.caffeine.cache.Caffeine.newBuilder()
-                .build();
+        this(cachingPerformance, null);
     }
 
-    public Caffeine(CachePerformance cachingPerformance, long ttl) {
-        this.cachePerformance = cachingPerformance;
-        this.cache = com.github.benmanes.caffeine.cache.Caffeine.newBuilder()
-                .expireAfterWrite(ttl, TimeUnit.MILLISECONDS)
-                .build();
+    public Caffeine(CachePerformance cachingPerformance, Long defaultTTL) {
+        this(cachingPerformance, defaultTTL, null);
     }
 
-    public Caffeine(CachePerformance cachingPerformance, Long ttl, long size) {
+    public Caffeine(CachePerformance cachingPerformance, Long defaultTTL, Long size) {
         this.cachePerformance = cachingPerformance;
-        if (ttl == null) {
-            this.cache = com.github.benmanes.caffeine.cache.Caffeine.newBuilder()
-                    .maximumSize(size)
-                    .build();
-
-        } else {
-            this.cache = com.github.benmanes.caffeine.cache.Caffeine.newBuilder()
-                    .expireAfterWrite(ttl, TimeUnit.MILLISECONDS)
-                    .maximumSize(size)
-                    .build();
-
+        this.keyHasTTL = new ConcurrentHashMap<>();
+        com.github.benmanes.caffeine.cache.Caffeine<Optional<K>, Optional<V>> builder = com.github.benmanes.caffeine.cache.Caffeine.newBuilder()
+                .expireAfter(new Expiry<Optional<K>, Optional<V>>() {
+                    @Override
+                    public long expireAfterCreate(Optional<K> key, Optional<V> value, long currentTime) {
+                        Long customTTL = keyHasTTL.remove(key);
+                        if (customTTL != null) {
+                            return customTTL * 1000000;
+                        }
+                        if (defaultTTL == null) {
+                            return Long.MAX_VALUE;
+                        }
+                        long ttlNanoseconds = defaultTTL * 1000000;
+                        if (ttlNanoseconds < 0) {
+                            return Long.MAX_VALUE;
+                        }
+                        return ttlNanoseconds;
+                    }
+
+                    @Override
+                    public long expireAfterUpdate(Optional<K> key, Optional<V> value, long currentTime, long currentDuration) {
+                        return expireAfterCreate(key, value, currentTime);
+                    }
+
+                    @Override
+                    public long expireAfterRead(Optional<K> key, Optional<V> value, long currentTime, long currentDuration) {
+                        return currentDuration;
+                    }
+                });
+        if (size != null) {
+            builder.maximumSize(size);
         }
+        builder.removalListener((k, v, cause) -> {
+            registerEvent(EventType.INVALIDATION, v.orElse(null));
+        });
+        this.cache = builder.build();
     }
 
     public CachePerformance getCachePerformance() {
@@ -81,6 +102,7 @@ public class Caffeine<K, V> implements Cache<K, V> {
 
     @Override
     public void put(K key, V value, long timeToLive) {
+        this.keyHasTTL.put(Optional.ofNullable(key), timeToLive);
         put(key, value);
     }
 
diff --git a/src/main/java/br/ufrgs/inf/prosoft/cache/CaffeineSingleCache.java b/src/main/java/br/ufrgs/inf/prosoft/cache/CaffeineSingleCache.java
index 51ef925..6e32697 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/cache/CaffeineSingleCache.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/cache/CaffeineSingleCache.java
@@ -22,11 +22,11 @@ public class CaffeineSingleCache<K, V> extends Caffeine<K, V> {
     }
 
     public CaffeineSingleCache(CachePerformance cachingPerformance) {
-        super(cachingPerformance, null, 1);
+        super(cachingPerformance, null, 1L);
     }
 
     public CaffeineSingleCache(CachePerformance cachingPerformance, long ttl) {
-        super(cachingPerformance, ttl, 1);
+        super(cachingPerformance, ttl, 1L);
     }
 
 }