Reducer.java

169 lines | 6.688 kB Blame History Raw Download
/*
 * 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 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.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;

/**
 *
 * @author romulo
 */
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.entrySet().stream().forEach(entry -> {
                    try {
                        fileWriter.write(prefix + entry.getKey() + "," + entry.getValue() + "\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();
            lines.forEach(new Consumer<String>() {
                int second = 0;

                @Override
                public void accept(String line) {
                    CacheEvent event = gson.fromJson(line, CacheEvent.class);
                    if (!event.getType().equals(EventType.POPULATION)) {
                        return;
                    }
                    try (FileWriter fileWriter = new FileWriter(reducePath, true)) {
                        fileWriter.write(prefix + event.getName() + "," + this.second + "," + event.getIdentifier() + "\n");
                    } catch (IOException ex) {
                        LOGGER.log(Level.SEVERE, "output error {0}", eventsPath);
                    }
                    this.second++;
                }
            });
        } catch (IOException ex) {
            LOGGER.log(Level.SEVERE, "input 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;
        }

    }

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

}