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 832f9a8..9946f6d 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/cache/Caffeine.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/cache/Caffeine.java
@@ -20,11 +20,9 @@ public class Caffeine<K, V> implements Cache<K, V>, AutoCloseable {
   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 static final boolean CACHE_REFRESH_TTL = System.getenv("CACHE_REFRESH_TTL") != null && System.getenv("CACHE_REFRESH_TTL").equals("true");
-
+  private static final Map<String, Long> METHOD_HAS_TTL = new HashMap<>();
   private static String CACHE_METHODS_TTL = System.getenv("CACHE_METHODS_TTL") != null && !System.getenv("CACHE_METHODS_TTL").isEmpty() && !System.getenv("CACHE_METHODS_TTL").equals("null")
     ? System.getenv("CACHE_METHODS_TTL") : null;
-  private static final Map<String, Long> METHOD_HAS_TTL = new HashMap<>();
-
   private final com.github.benmanes.caffeine.cache.Cache<Optional<K>, Optional<V>> cache;
   private final ConcurrentHashMap<Optional<K>, Long> keyHasTTL;
   private final CachePerformance cachePerformance;
@@ -62,7 +60,7 @@ public class Caffeine<K, V> implements Cache<K, V>, AutoCloseable {
     this.cachePerformance = cachingPerformance;
     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>>() {
+      .expireAfter(new Expiry<>() {
         @Override
         public long expireAfterCreate(Optional<K> key, Optional<V> value, long currentTime) {
           Long customTTL = keyHasTTL.remove(key);
@@ -140,7 +138,8 @@ public class Caffeine<K, V> implements Cache<K, V>, AutoCloseable {
       if (ttl > 0) this.keyHasTTL.put(Optional.ofNullable(key), ttl);
     }
     this.cache.put(Optional.ofNullable(key), Optional.ofNullable(value));
-    registerEvent(EventType.ADDITION, value);
+    if (this.cache.getIfPresent(Optional.ofNullable(key)) != null) registerEvent(EventType.REPLACE, value);
+    else registerEvent(EventType.ADDITION, value);
   }
 
   @Override
diff --git a/src/main/java/br/ufrgs/inf/prosoft/cache/EventType.java b/src/main/java/br/ufrgs/inf/prosoft/cache/EventType.java
index f80036b..cd7d9fb 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/cache/EventType.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/cache/EventType.java
@@ -6,9 +6,8 @@
 package br.ufrgs.inf.prosoft.cache;
 
 /**
- *
  * @author romulo
  */
 public enum EventType {
-    HIT, MISS, ADDITION, INVALIDATION, POPULATION;
+    HIT, MISS, ADDITION, INVALIDATION, POPULATION, REPLACE
 }
diff --git a/src/main/java/br/ufrgs/inf/prosoft/cache/tools/Reducer.java b/src/main/java/br/ufrgs/inf/prosoft/cache/tools/Reducer.java
index 5254586..805ffe4 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/cache/tools/Reducer.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/cache/tools/Reducer.java
@@ -17,150 +17,160 @@ import java.util.stream.Stream;
 
 public class Reducer {
 
-    private static final Logger LOGGER = Logger.getLogger(Reducer.class.getName());
-
-    public static void reduce(String eventsPath, String reducePath, String prefix) {
-        try (Stream<String> lines = Files.lines(Paths.get(eventsPath))) {
-            Gson gson = new Gson();
-            Map<String, Integer> objectHasHits = new HashMap<>();
-            lines.forEach(line -> {
-                CacheEvent event = gson.fromJson(line, CacheEvent.class);
-                if (event.getType().equals(EventType.HIT) || event.getType().equals(EventType.ADDITION) || event.getType().equals(EventType.MISS)) {
-                    String identifier = event.getName() + "," + event.getIdentifier() + "," + event.getType().name().toLowerCase();
-                    try {
-                        objectHasHits.put(identifier, objectHasHits.get(identifier) + 1);
-                    } catch (Exception ex) {
-                        objectHasHits.put(identifier, 1);
-                    }
-                }
-            });
-
-            try (FileWriter fileWriter = new FileWriter(reducePath, true)) {
-                objectHasHits.forEach((key, value) -> {
-                    try {
-                        fileWriter.write(prefix + key + "," + value + "\n");
-                    } catch (IOException ex) {
-                        LOGGER.log(Level.SEVERE, "IOException {0}", ex);
-                    }
-                });
-            }
-        } catch (IOException ex) {
-            LOGGER.log(Level.SEVERE, "file not found {0}", eventsPath);
+  private static final Logger LOGGER = Logger.getLogger(Reducer.class.getName());
+
+  public static void reduce(String eventsPath, String reducePath, String prefix) {
+    try (Stream<String> lines = Files.lines(Paths.get(eventsPath))) {
+      Gson gson = new Gson();
+      Map<String, Integer> objectHasHits = new HashMap<>();
+      lines.forEach(line -> {
+        CacheEvent event = gson.fromJson(line, CacheEvent.class);
+        if (event.getType().equals(EventType.HIT) || event.getType().equals(EventType.ADDITION) || event.getType().equals(EventType.MISS)) {
+          String identifier = event.getName() + "," + event.getIdentifier() + "," + event.getType().name().toLowerCase();
+          try {
+            objectHasHits.put(identifier, objectHasHits.get(identifier) + 1);
+          } catch (Exception ex) {
+            objectHasHits.put(identifier, 1);
+          }
         }
+      });
+
+      try (FileWriter fileWriter = new FileWriter(reducePath, true)) {
+        objectHasHits.forEach((key, value) -> {
+          try {
+            fileWriter.write(prefix + key + "," + value + "\n");
+          } catch (IOException ex) {
+            LOGGER.log(Level.SEVERE, "IOException {0}", ex);
+          }
+        });
+      }
+    } catch (IOException ex) {
+      LOGGER.log(Level.SEVERE, "file not found {0}", eventsPath);
     }
-
-    public static void size(String eventsPath, String reducePath, String prefix) {
-        try (Stream<String> lines = Files.lines(Paths.get(eventsPath))) {
-            Gson gson = new Gson();
-            List<CacheEvent> events = lines
-              .map(it -> gson.fromJson(it, CacheEvent.class))
-              .sorted(Comparator.comparingLong(CacheEvent::getTime))
-              .collect(Collectors.toList());
-            long startTime = events.get(0).getTime();
-            try (FileWriter fileWriter = new FileWriter(reducePath, true)) {
-                AtomicLong currentCacheSize = new AtomicLong();
-                fileWriter.write(prefix + events.get(0).getName() + "," + 0 + "," + currentCacheSize + "\n");
-                events.forEach(it -> {
-                    if (it.getType().equals(EventType.ADDITION)) currentCacheSize.getAndIncrement();
-                    else if (it.getType().equals(EventType.INVALIDATION)) currentCacheSize.getAndDecrement();
-                    else return;
-                    try {
-                        long adjustedTime = it.getTime() - startTime;
-                        fileWriter.write(prefix + it.getName() + "," + adjustedTime + "," + currentCacheSize + "\n");
-                    } catch (IOException ex) {
-                        LOGGER.log(Level.SEVERE, "output error {0}", reducePath);
-                    }
-                });
-                long endTime = events.get(events.size() - 1).getTime() - startTime;
-                fileWriter.write(prefix + events.get(events.size() - 1).getName() + "," + endTime + "," + currentCacheSize + "\n");
-            } catch (IOException ex) {
+  }
+
+  public static void size(String eventsPath, String reducePath, String prefix) {
+    try (Stream<String> lines = Files.lines(Paths.get(eventsPath))) {
+      Gson gson = new Gson();
+      List<CacheEvent> events = lines
+        .map(it -> gson.fromJson(it, CacheEvent.class))
+        .sorted(Comparator.comparingLong(CacheEvent::getTime))
+        .collect(Collectors.toList());
+      long startTime = events.get(0).getTime();
+      try (FileWriter fileWriter = new FileWriter(reducePath, true)) {
+        AtomicLong currentCacheSize = new AtomicLong();
+        fileWriter.write(prefix + events.get(0).getName() + "," + 0 + "," + currentCacheSize + "\n");
+        events.forEach(it -> {
+          if (it.getType().equals(EventType.ADDITION) || it.getType().equals(EventType.REPLACE)) {
+            if ((it.getName().contains(":single-") || it.getName().contains(":getter-")) && currentCacheSize.get() == 1 || it.getType().equals(EventType.REPLACE)) {
+              currentCacheSize.getAndDecrement();
+              try {
+                long adjustedTime = it.getTime() - startTime;
+                fileWriter.write(prefix + it.getName() + "," + adjustedTime + "," + currentCacheSize + "\n");
+              } catch (IOException ex) {
                 LOGGER.log(Level.SEVERE, "output error {0}", reducePath);
+              }
             }
-        } catch (IOException ex) {
-            LOGGER.log(Level.SEVERE, "output error {0}", eventsPath);
-        }
+            currentCacheSize.getAndIncrement();
+          } else if (it.getType().equals(EventType.INVALIDATION)) currentCacheSize.getAndDecrement();
+          else return;
+          try {
+            long adjustedTime = it.getTime() - startTime;
+            fileWriter.write(prefix + it.getName() + "," + adjustedTime + "," + currentCacheSize + "\n");
+          } catch (IOException ex) {
+            LOGGER.log(Level.SEVERE, "output error {0}", reducePath);
+          }
+        });
+        long endTime = events.get(events.size() - 1).getTime() - startTime;
+        fileWriter.write(prefix + events.get(events.size() - 1).getName() + "," + endTime + "," + currentCacheSize + "\n");
+      } catch (IOException ex) {
+        LOGGER.log(Level.SEVERE, "output error {0}", reducePath);
+      }
+    } catch (IOException ex) {
+      LOGGER.log(Level.SEVERE, "output error {0}", eventsPath);
     }
+  }
+
+  public static void savedTimeAndTimeInCache(String eventsPath, String recommendedTTLsPath, String averageExecutionsPath, String reducePath, String prefix) {
+    CSV recommendedTTLs = CSV.read(recommendedTTLsPath);
+    CSV averageExecutions = CSV.read(averageExecutionsPath);
+
+    Map<String, Method> methods = new HashMap<>();
+
+    recommendedTTLs.forEach(row -> {
+      String reference = row.get("reference");
+      Optional<CSV.Row> selectFirst = averageExecutions.selectFirst("reference", reference);
+      if (selectFirst.isPresent()) {
+        Method method = new Method();
+        method.reference = reference;
+        method.ttl = Long.parseLong(row.get("ttl"));
+        method.avgexecution = Double.parseDouble(selectFirst.get().get("avgexecution"));
+        if (methods.containsKey(reference)) {
+          throw new RuntimeException("Trying to overwrite reference " + reference);
+        }
+        String uuid = row.get("application") + "," + row.get("version") + "," + row.get("group") + "," + row.get("method");
+        methods.put(uuid, method);
+      }
+    });
+
+    String[] splitPrefix = prefix.split(",");
+    String application = splitPrefix[0];
+    String version = splitPrefix[1];
+    String group = splitPrefix[2];
+
+    String uuid = application + "," + version + "," + group + ",";
+
+    try (Stream<String> lines = Files.lines(Paths.get(eventsPath))) {
+      Gson gson = new Gson();
+      lines.forEach(line -> {
+        CacheEvent event = gson.fromJson(line, CacheEvent.class);
+        if (event.getType().equals(EventType.HIT) || event.getType().equals(EventType.ADDITION)) {
+          Method method = methods.get(uuid + event.getName());
+          if (method == null) {
+            LOGGER.log(Level.FINE, "Method in events was not recommended {0}{1}", new Object[]{uuid, event.getName()});
+            return;
+          }
+          if (event.getType().equals(EventType.HIT)) {
+            method.hits++;
+          } else {
+            method.additions++;
+          }
+        }
+      });
 
-    public static void savedTimeAndTimeInCache(String eventsPath, String recommendedTTLsPath, String averageExecutionsPath, String reducePath, String prefix) {
-        CSV recommendedTTLs = CSV.read(recommendedTTLsPath);
-        CSV averageExecutions = CSV.read(averageExecutionsPath);
-
-        Map<String, Method> methods = new HashMap<>();
-
-        recommendedTTLs.forEach(row -> {
-            String reference = row.get("reference");
-            Optional<CSV.Row> selectFirst = averageExecutions.selectFirst("reference", reference);
-            if (selectFirst.isPresent()) {
-                Method method = new Method();
-                method.reference = reference;
-                method.ttl = Long.parseLong(row.get("ttl"));
-                method.avgexecution = Double.parseDouble(selectFirst.get().get("avgexecution"));
-                if (methods.containsKey(reference)) {
-                    throw new RuntimeException("Trying to overwrite reference " + reference);
-                }
-                String uuid = row.get("application") + "," + row.get("version") + "," + row.get("group") + "," + row.get("method");
-                methods.put(uuid, method);
+      try (FileWriter fileWriter = new FileWriter(reducePath, true)) {
+        methods.values().forEach(method -> {
+          try {
+            if (method.hits + method.additions > 0) {
+              fileWriter.write(prefix + method.reference + "," + method.avgexecution + "," + method.ttl + "," + method.additions + "," + method.hits + "," + method.getSavedTime() + "," + method.getTimeInCache() + "\n");
             }
+          } catch (IOException ex) {
+            LOGGER.log(Level.SEVERE, "IOException {0}", ex);
+          }
         });
-
-        String[] splitPrefix = prefix.split(",");
-        String application = splitPrefix[0];
-        String version = splitPrefix[1];
-        String group = splitPrefix[2];
-
-        String uuid = application + "," + version + "," + group + ",";
-
-        try (Stream<String> lines = Files.lines(Paths.get(eventsPath))) {
-            Gson gson = new Gson();
-            lines.forEach(line -> {
-                CacheEvent event = gson.fromJson(line, CacheEvent.class);
-                if (event.getType().equals(EventType.HIT) || event.getType().equals(EventType.ADDITION)) {
-                    Method method = methods.get(uuid + event.getName());
-                    if (method == null) {
-                        LOGGER.log(Level.FINE, "Method in events was not recommended {0}{1}", new Object[]{uuid, event.getName()});
-                        return;
-                    }
-                    if (event.getType().equals(EventType.HIT)) {
-                        method.hits++;
-                    } else {
-                        method.additions++;
-                    }
-                }
-            });
-
-            try (FileWriter fileWriter = new FileWriter(reducePath, true)) {
-                methods.values().forEach(method -> {
-                    try {
-                        if (method.hits + method.additions > 0) {
-                            fileWriter.write(prefix + method.reference + "," + method.avgexecution + "," + method.ttl + "," + method.additions + "," + method.hits + "," + method.getSavedTime() + "," + method.getTimeInCache() + "\n");
-                        }
-                    } catch (IOException ex) {
-                        LOGGER.log(Level.SEVERE, "IOException {0}", ex);
-                    }
-                });
-            }
-        } catch (IOException ex) {
-            LOGGER.log(Level.SEVERE, "file not found {0}", eventsPath);
-        }
+      }
+    } catch (IOException ex) {
+      LOGGER.log(Level.SEVERE, "file not found {0}", eventsPath);
     }
+  }
 
-    private static class Method {
+  private static class Method {
 
-        String name;
-        String reference;
-        long ttl;
-        double avgexecution;
-        int hits;
-        int additions;
-
-        double getSavedTime() {
-            return avgexecution * hits;
-        }
+    String name;
+    String reference;
+    long ttl;
+    double avgexecution;
+    int hits;
+    int additions;
 
-        long getTimeInCache() {
-            return ttl * additions;
-        }
+    double getSavedTime() {
+      return avgexecution * hits;
+    }
 
+    long getTimeInCache() {
+      return ttl * additions;
     }
 
+  }
+
 }