Method.java

125 lines | 4.039 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.aplcache.metadata;

import br.ufrgs.inf.prosoft.aplcache.flowchart.metrics.CacheabilityPatternDecider;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

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

    private static final Logger LOGGER = Logger.getLogger(Method.class.getName());
    private static final boolean TRACER_VERBOSE = System.getenv("TRACER_VERBOSE") == null || !System.getenv("TRACER_VERBOSE").equals("false");

    private final String name;
    private final List<Occurrence> occurrences;
    private List<GroupOfOccurrences> groupsOfOccurrences;

    public Method(String name) {
        this.name = name;
        this.occurrences = new ArrayList<>();
    }

    public String getName() {
        return name;
    }

    public Method addOccurrence(Occurrence occurrence) {
        this.occurrences.add(occurrence);
        return this;
    }

    public Method clearTraces() {
        this.occurrences.clear();
        return this;
    }

    public int getOccurrencesSize() {
        return this.occurrences.size();
    }

    public List<GroupOfOccurrences> getGroupsOfOccurrences() {
        return groupsOfOccurrences;
    }

    public void groupByParameter() {
        LOGGER.log(Level.INFO, "Grouping by parameters {0} occurrences of {1}", new Object[]{this.name, this.occurrences.size()});
        Map<String, GroupOfOccurrences> groupByParameter = new HashMap<>();
        this.occurrences.stream().parallel().forEach(new Consumer<Occurrence>() {

            private int i;
            private final Gson gson;

            {
                this.i = 0;
                this.gson = new Gson();
            }

            @Override
            public void accept(Occurrence occurrence) {
                if (TRACER_VERBOSE) {
                    System.out.print(".");
                    System.out.flush();
                    if (++this.i % 100 == 0) {
                        System.out.println();
                    }
                }
                String parameters = this.gson.toJson(occurrence.getParameters());
                synchronized (groupByParameter) {
                    try {
                        groupByParameter.get(parameters).addOccurrence(occurrence);
                    } catch (Exception e) {
                        GroupOfOccurrences groupOfOccurrences = new GroupOfOccurrences(parameters);
                        groupOfOccurrences.addOccurrence(occurrence);
                        groupByParameter.put(parameters, groupOfOccurrences);
                    }
                }
            }
        });
        this.groupsOfOccurrences = groupByParameter.values().stream().collect(Collectors.toList());
        groupByParameter.clear();
        this.occurrences.clear();
    }

    public void calculateMetrics() {
        groupByParameter();
        Collections.sort(this.groupsOfOccurrences, (g1, g2) -> Integer.compare(g1.getOccurrencesSize(), g2.getOccurrencesSize()));
        this.groupsOfOccurrences.stream().parallel().forEach(GroupOfOccurrences::calculateMetrics);
    }

    public void calculateThresholds() {
        this.groupsOfOccurrences.stream().forEach(GroupOfOccurrences::calculateThresholds);
    }

    public void filterCacheableInputs() {
        Iterator<GroupOfOccurrences> iterator = this.groupsOfOccurrences.iterator();
        while (iterator.hasNext()) {
            GroupOfOccurrences groupOfOccurrences = iterator.next();
            if (!CacheabilityPatternDecider.isCacheable(groupOfOccurrences)) {
                iterator.remove();
            }
        }
    }

    @Override
    public String toString() {
        return this.name;
    }
}