cache

replaced a ttl thread pet key by a scheduleexecutor iterating

7/6/2019 7:09:59 AM

Details

diff --git a/src/main/java/br/ufrgs/inf/prosoft/cache/MultiCache.java b/src/main/java/br/ufrgs/inf/prosoft/cache/MultiCache.java
index 784df70..ff8c160 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/cache/MultiCache.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/cache/MultiCache.java
@@ -8,8 +8,12 @@ package br.ufrgs.inf.prosoft.cache;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
-import java.util.logging.Level;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 import java.util.logging.Logger;
 import java.util.stream.Collectors;
 
@@ -23,7 +27,7 @@ public class MultiCache<K, V> implements Cache<K, V> {
 
     private static final boolean CACHE_REGISTER_SIZE = System.getenv("CACHE_REGISTER_SIZE") != null && System.getenv("CACHE_REGISTER_SIZE").equals("true");
     private final HashMap<K, V> map;
-    private final HashMap<K, Thread> keyHasTTL;
+    private final ConcurrentHashMap<Optional<K>, Long> keyHasTTL;
     private final CachePerformance cachePerformance;
     private static final Logger LOGGER = Logger.getLogger(Cache.class.getName());
 
@@ -38,7 +42,17 @@ public class MultiCache<K, V> implements Cache<K, V> {
     public MultiCache(CachePerformance cachingPerformance) {
         this.cachePerformance = cachingPerformance;
         this.map = new HashMap<>();
-        this.keyHasTTL = new HashMap<>();
+        this.keyHasTTL = new ConcurrentHashMap<>();
+
+        ScheduledExecutorService timeToLiveUpdater = Executors.newScheduledThreadPool(1);
+        timeToLiveUpdater.scheduleAtFixedRate(() -> {
+            this.keyHasTTL.forEach((key, value) -> {
+                if (value == 0) {
+                    invalidate(key.orElse(null));
+                }
+                this.keyHasTTL.put(key, value--);
+            });
+        }, 1, 1, TimeUnit.MILLISECONDS);
     }
 
     public CachePerformance getCachePerformance() {
@@ -48,16 +62,7 @@ public class MultiCache<K, V> implements Cache<K, V> {
     @Override
     public void put(K key, V value, long timeToLive) {
         put(key, value);
-        Thread thread = new Thread(() -> {
-            try {
-                Thread.sleep(timeToLive);
-                invalidate(key);
-            } catch (InterruptedException ex) {
-                LOGGER.log(Level.WARNING, "interrupted time to live");
-            }
-        });
-        this.keyHasTTL.put(key, thread);
-        thread.start();
+        this.keyHasTTL.put(Optional.ofNullable(key), timeToLive);
     }
 
     @Override
@@ -91,10 +96,7 @@ public class MultiCache<K, V> implements Cache<K, V> {
 
     @Override
     public void invalidate(K key) {
-        Thread timeToLiveThread = this.keyHasTTL.remove(key);
-        if (timeToLiveThread != null) {
-            timeToLiveThread.interrupt();
-        }
+        this.keyHasTTL.remove(Optional.ofNullable(key));
         if (this.map.containsKey(key)) {
             V remove = this.map.remove(key);
             String identifier = getIdentifier(remove);