TFCache.java

126 lines | 6.05 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.tfcache;

import br.ufrgs.inf.prosoft.tfcache.configuration.Configuration;
import br.ufrgs.inf.prosoft.tfcache.metadata.Method;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;

/**
 *
 * @author romulo
 */
public class TFCache {

    private static final Logger LOGGER = Logger.getLogger(TFCache.class.getName());
    private final List<Method> methods;

    public TFCache(List<Method> methods) {
        this.methods = methods;
    }

    public Stream<Method> methods() {
        return this.methods.stream();
    }

    private void recommendCacheableMethods() {
        if (Configuration.getChangeability().equals("deny")) {
            LOGGER.log(Level.INFO, "Removing changeable from {0} methods", this.methods.size());
            this.methods.removeIf(Method::isChangeable);
        }
        LOGGER.log(Level.INFO, "Removing not reusable from {0} methods", this.methods.size());
        this.methods.removeIf(Method::isNotReusable);
        LOGGER.log(Level.INFO, "Recommending TTL to {0} methods", this.methods.size());
        this.methods.stream().parallel().forEach(Method::recommendTTL);
        LOGGER.log(Level.INFO, "Removing not recommended from {0}", this.methods.size());
        this.methods.removeIf(method -> method.getSavedTime() == 0);
        LOGGER.log(Level.INFO, "Ranking {0} methods according saved time", this.methods.size());
        this.methods.sort((method1, method2) -> Long.compare(method2.getSavedTime(), method1.getSavedTime()));
        LOGGER.log(Level.INFO, "Printing recommendations for {0} methods", this.methods.size());
        this.methods.forEach(method -> {
            System.out.println(method.getName()
                    + " Occurrences " + method.getOccurrencesSize()
                    + " Inputs " + method.groupsOfOccurrences().count()
                    + " TTL " + method.getTtl()
                    + " STpTiC " + method.getSavedTimePerTimeInCache()
                    + " Saves " + method.getSavedTime()
                    + " Hits " + method.getBestMetrics().getHits()
                    + " Stales " + method.getBestMetrics().getStales());
        });
    }

    private void recommendCacheableInputs() {
        if (Configuration.getChangeability().equals("deny")) {
            LOGGER.log(Level.INFO, "Removing changeable inputs from {0} methods", this.methods.size());
            this.methods.forEach(Method::removeChangeableInputs);
        }
        LOGGER.log(Level.INFO, "Removing not reusable inputs from {0} methods", this.methods.size());
        this.methods.forEach(Method::removeSingleOccurrences);
        LOGGER.log(Level.INFO, "Removing not reusable methods from {0} methods", this.methods.size());
        this.methods.removeIf(method -> method.groupsOfOccurrences().count() < 1);
        LOGGER.log(Level.INFO, "Recommending TTL to {0} methods", this.methods.size());
        this.methods.stream().parallel().forEach(Method::recommendTTLPerInput);
        LOGGER.log(Level.INFO, "Removing not recommended inputs from {0}", this.methods.size());
        this.methods.forEach(Method::removeNotRecommededInputs);
        LOGGER.log(Level.INFO, "Removing not recommended methods from {0}", this.methods.size());
        this.methods.removeIf(method -> method.groupsOfOccurrences().count() < 1);
        LOGGER.log(Level.INFO, "Ranking {0} methods and inputs according saved time", this.methods.size());
        this.methods.forEach(Method::rankRecommendations);
        this.methods.sort((method1, method2) -> Long.compare(method2.getSavedTime(), method1.getSavedTime()));
        LOGGER.log(Level.INFO, "Printing recommendations for {0} methods", this.methods.size());
        this.methods.forEach(method -> {
            System.out.println(method.getName()
                    + " Occurrences " + method.getOccurrencesSize()
                    + " Inputs " + method.groupsOfOccurrences().count()
                    + " TTL " + method.getTtl()
                    + " STpTiC " + method.getSavedTimePerTimeInCache()
                    + " Saves " + method.getSavedTime()
                    + " Hits " + method.getBestMetrics().getHits()
                    + " Stales " + method.getBestMetrics().getStales());
            method.groupsOfOccurrences().forEach(group -> {
                System.out.println("\t" + group.getParameters().hashCode()
                        + " Occurrences " + group.getOccurrencesSize()
                        + " -> TTL " + group.getTtl()
                        + " STpTiC " + group.getSavedTimePerTimeInCache()
                        + " Saves " + group.getSavedTime()
                        + " Hits " + group.getBestMetrics().getHits()
                        + " Stales " + group.getBestMetrics().getHits());
            });
        });
        try (FileWriter fileWriter = new FileWriter(Configuration.getOutput())) {
            JsonObject jsonCacheableParameters = new JsonObject();
            this.methods.forEach(method -> {
                JsonObject cacheableParameters = new JsonObject();
                method.groupsOfOccurrences().forEach(group -> {
                    cacheableParameters.addProperty(group.getParameters(), group.getTtl());
                });
                jsonCacheableParameters.add(method.getName(), cacheableParameters);
            });
            Gson gson = new GsonBuilder().setPrettyPrinting().create();
            gson.toJson(jsonCacheableParameters, fileWriter);
        } catch (IOException ex) {
            LOGGER.log(Level.SEVERE, "invalid <outputPath>");
        }
    }

    public void recommend() {
        if (Configuration.getLevel().equals("method")) {
            recommendCacheableMethods();
        } else {
            recommendCacheableInputs();
        }
    }

}