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);
+ }
+ }
+
}