diff --git a/src/main/java/br/ufrgs/inf/prosoft/cache/tools/Distinct.java b/src/main/java/br/ufrgs/inf/prosoft/cache/tools/Distinct.java
new file mode 100644
index 0000000..eff11be
--- /dev/null
+++ b/src/main/java/br/ufrgs/inf/prosoft/cache/tools/Distinct.java
@@ -0,0 +1,76 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package br.ufrgs.inf.prosoft.cache.tools;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Stream;
+
+/**
+ *
+ * @author romulo
+ */
+public class Distinct {
+
+ private static final Logger LOGGER = Logger.getLogger(Reducer.class.getName());
+
+ public static void reduce(String uncachedPath, String reducePath, String prefix) {
+ reduce(uncachedPath, reducePath, prefix, true);
+ }
+
+ public static void reduce(String uncachedPath, String reducePath, String prefix, boolean hash) {
+ MessageDigest messageDigest;
+ try {
+ messageDigest = MessageDigest.getInstance("sha-512");
+ } catch (NoSuchAlgorithmException ex) {
+ LOGGER.log(Level.SEVERE, "Cannot hash");
+ return;
+ }
+ Map<String, Map<String, Integer>> methodHasParametersUsage = new HashMap<>();
+ try (Stream<String> lines = Files.lines(Paths.get(uncachedPath))) {
+ lines.forEach(line -> {
+ if (line.startsWith("uncacheable ")) {
+ String[] split = line.split(" ");
+ methodHasParametersUsage.compute(split[1], (key, previous) -> {
+ if (previous == null) {
+ previous = new HashMap<>();
+ }
+ previous.merge(split[3], 1, (innerPrevious, innerBase) -> innerPrevious + innerBase);
+ return previous;
+ });
+ }
+ });
+
+ try (FileWriter fileWriter = new FileWriter(reducePath, true)) {
+ methodHasParametersUsage.entrySet().stream().forEach(entry -> {
+ entry.getValue().entrySet().forEach(innerEntry -> {
+ try {
+ String parameters = innerEntry.getKey();
+ if (hash) {
+ parameters = String.valueOf(messageDigest.digest(parameters.getBytes()));
+ }
+ fileWriter.write(prefix + entry.getKey() + "," + parameters + "," + innerEntry.getValue() + "\n");
+ } catch (IOException ex) {
+ LOGGER.log(Level.SEVERE, "IOException {0}", ex);
+ }
+ });
+ });
+ } catch (IOException ex) {
+ Logger.getLogger(Distinct.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ } catch (IOException ex) {
+ LOGGER.log(Level.SEVERE, "file not found {0}", uncachedPath);
+ }
+ }
+}
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 d6a4779..abb96fc 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
@@ -5,6 +5,10 @@
*/
package br.ufrgs.inf.prosoft.cache.tools;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
/**
*
* @author romulo
@@ -14,13 +18,42 @@ public class Main {
public static void main(String[] args) {
System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tF %1$tT+%1$tL] [%4$-7s] [Cache] %5$s %n");
- if (args.length < 3) {
- System.err.println("<EventsPath> <ReducePath> <prefix>");
+ if (args.length < 2) {
+ System.err.println("--events=<EventsPath> --reduce=<ReducePath> [--prefix=<prefix>]");
+ System.err.println("--uncached=<UncachedPath> --reduce=<ReducePath> [--prefix=<prefix> --hash]");
+ System.exit(1);
+ }
+
+ Map<String, String> arguments = Stream.of(args).map(arg -> {
+ arg = arg.replaceFirst("--", "");
+ int indexOf = arg.indexOf("=");
+ if (indexOf == -1) {
+ return new String[]{arg, ""};
+ }
+ return new String[]{arg.substring(0, indexOf), arg.substring(indexOf + 1)};
+ }).collect(Collectors.toMap(array -> {
+ return array[0];
+ }, array -> {
+ return array[1];
+ }));
+
+ String eventsPath = arguments.get("events");
+ 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");
System.exit(1);
}
- String eventsPath = args[0];
- String reducePath = args[1];
- String prefix = args[2];
- Reducer.reduce(eventsPath, reducePath, prefix);
+ if (prefix == null) {
+ prefix = "";
+ }
+ if (eventsPath != null) {
+ Reducer.reduce(eventsPath, reducePath, prefix);
+ }
+ if (uncachedPath != null) {
+ boolean hash = arguments.get("hash") != null;
+ Distinct.reduce(uncachedPath, reducePath, prefix, hash);
+ }
}
}