Reducer.java

167 lines | 7.159 kB Blame History Raw Download
package br.ufrgs.inf.prosoft.cache.tools;

import br.ufrgs.inf.prosoft.cache.CacheEvent;
import br.ufrgs.inf.prosoft.cache.EventType;
import com.google.gson.Gson;

import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
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);
        }
    }

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

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

    private static class Method {

        String name;
        String reference;
        long ttl;
        double avgexecution;
        int hits;
        int additions;

        double getSavedTime() {
            return avgexecution * hits;
        }

        long getTimeInCache() {
            return ttl * additions;
        }

    }

}