cache

added size reducer

4/12/2020 8:42:17 PM

Details

diff --git a/src/main/java/br/ufrgs/inf/prosoft/cache/tools/Main.java b/src/main/java/br/ufrgs/inf/prosoft/cache/tools/Main.java
index abb96fc..7516af9 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/cache/tools/Main.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/cache/tools/Main.java
@@ -21,6 +21,7 @@ public class Main {
         if (args.length < 2) {
             System.err.println("--events=<EventsPath> --reduce=<ReducePath> [--prefix=<prefix>]");
             System.err.println("--uncached=<UncachedPath> --reduce=<ReducePath> [--prefix=<prefix> --hash]");
+            System.err.println("--events=<EventsPath> --reduce=<ReducePath> --size=true [--prefix=<prefix>]");
             System.exit(1);
         }
 
@@ -41,17 +42,19 @@ public class Main {
         String reducePath = arguments.get("reduce");
         String prefix = arguments.get("prefix");
         String uncachedPath = arguments.get("uncached");
-        if (reducePath == null && uncachedPath == null) {
-            System.err.println("<ReducePath> or <UncachedPath> is required");
+        String size = arguments.get("size");
+        if (reducePath == null && (eventsPath == null || uncachedPath == null)) {
+            System.err.println("<ReducePath> and either <EventsPath> or <UncachedPath> are required");
             System.exit(1);
         }
         if (prefix == null) {
             prefix = "";
         }
-        if (eventsPath != null) {
+        if (eventsPath != null && size != null) {
+            Reducer.size(eventsPath, reducePath, prefix);
+        } else if (eventsPath != null) {
             Reducer.reduce(eventsPath, reducePath, prefix);
-        }
-        if (uncachedPath != null) {
+        } else if (uncachedPath != null) {
             boolean hash = arguments.get("hash") != null;
             Distinct.reduce(uncachedPath, reducePath, prefix, hash);
         }
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 e6780e7..c9deb3d 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
@@ -13,7 +13,9 @@ import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.TreeMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.stream.Stream;
@@ -55,4 +57,67 @@ public class Reducer {
             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();
+            Map<String, TreeMap<Long, Integer>> cacheHasSizeAlongTime = new HashMap<>();
+            lines.forEach(line -> {
+                CacheEvent event = gson.fromJson(line, CacheEvent.class);
+                if (!(event.getType().equals(EventType.ADDITION) || event.getType().equals(EventType.INVALIDATION))) {
+                    return;
+                }
+                cacheHasSizeAlongTime.compute(event.getName(), (key, previous) -> {
+                    if (previous == null) {
+                        previous = new TreeMap<>();
+                    }
+                    previous.compute(event.getTime() / 1000, (innerKey, innerPrevious) -> {
+                        if (innerPrevious == null) {
+                            innerPrevious = 0;
+                        }
+                        if (event.getType().equals(EventType.ADDITION)) {
+                            return innerPrevious + 1;
+                        }
+                        return innerPrevious - 1;
+                    });
+                    return previous;
+                });
+            });
+
+            cacheHasSizeAlongTime.forEach((name, sizeAlongTime) -> {
+                Iterator<Map.Entry<Long, Integer>> iterator = sizeAlongTime.entrySet().iterator();
+                int accumulated = iterator.next().getValue();
+                while (iterator.hasNext()) {
+                    Map.Entry<Long, Integer> entry = iterator.next();
+                    accumulated += entry.getValue();
+                    entry.setValue(accumulated);
+                }
+            });
+
+            final Long baseTime = cacheHasSizeAlongTime.values().stream().map(map -> map.firstKey()).min(Long::compare).get();
+            final Long adjustedMaxTime = cacheHasSizeAlongTime.values().stream().map(map -> map.lastKey()).max(Long::compare).get() - baseTime;
+
+            try (FileWriter fileWriter = new FileWriter(reducePath, true)) {
+                cacheHasSizeAlongTime.forEach((name, sizeAlongTime) -> {
+                    try {
+                        Map.Entry<Long, Integer> pollFirstEntry = sizeAlongTime.pollFirstEntry();
+                        for (long i = 0; i < pollFirstEntry.getKey() - baseTime; i++) {
+                            fileWriter.write(prefix + name + "," + i + "," + 0 + "\n");
+                        }
+                        for (long i = pollFirstEntry.getKey() - baseTime; i <= adjustedMaxTime; i++) {
+                            if (sizeAlongTime.size() > 1 && i > pollFirstEntry.getKey() - baseTime) {
+                                pollFirstEntry = sizeAlongTime.pollFirstEntry();
+                            }
+                            fileWriter.write(prefix + name + "," + i + "," + pollFirstEntry.getValue() + "\n");
+                        }
+                    } catch (IOException ex) {
+                        LOGGER.log(Level.SEVERE, "file not found {0}", reducePath);
+                    }
+                });
+            }
+        } catch (IOException ex) {
+            LOGGER.log(Level.SEVERE, "file not found {0}", eventsPath);
+        }
+    }
+
 }