GroupOfOccurrences.java

130 lines | 4.437 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.aplcachetf.extension.metadata;

import br.ufrgs.inf.prosoft.aplcachetf.extension.metrics.Thresholds;
import br.ufrgs.inf.prosoft.aplcachetf.extension.metrics.Metrics;
import br.ufrgs.inf.prosoft.tfcache.Simulator;
import br.ufrgs.inf.prosoft.tfcache.metadata.Occurrence;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
import org.apache.commons.lang3.builder.EqualsBuilder;

/**
 *
 * @author root
 */
public class GroupOfOccurrences {

    private static final Logger LOGGER = Logger.getLogger(GroupOfOccurrences.class.getName());

    private final String parameters;
    private final List<Occurrence> occurrences;
    private Metrics bestMetrics;

    public GroupOfOccurrences(String parameters, List<Occurrence> occurrences) {
        this.parameters = parameters;
        this.occurrences = occurrences;
    }

    public String getParameters() {
        return this.parameters;
    }

    public Stream<Occurrence> occurrences() {
        return this.occurrences.stream();
    }

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

    public Metrics getBestMetrics() {
        if (this.bestMetrics == null) {
            throw new RuntimeException("hitsPerTimeInCache must be calculated");
        }
        return this.bestMetrics;
    }

    public Long getTtl() {
        return getBestMetrics().getTtl();
    }

    public Long getSavedTime() {
        return getBestMetrics().getSavedTime();
    }

    public BigDecimal getHitsPerTimeInCache() {
        return getBestMetrics().getHitsPerTimeInCache();
    }

    private void calculateHitsPerTimeInCache() {
        if (this.bestMetrics != null) {
            LOGGER.log(Level.WARNING, "HitsPerTimeInCache already calculated");
        }
        this.bestMetrics = new Metrics();

        Collection<Long> ttlsOfInterest = new HashSet<>();
        for (int hits = 1; hits < this.occurrences.size(); hits++) {
            for (int shift = 0; shift < this.occurrences.size() - hits; shift++) {
                long ttl = 0;
                for (int k = shift + 1; k < shift + 1 + hits; k++) {
                    ttl += this.occurrences.get(k).getStartTime() - this.occurrences.get(k - 1).getEndTime();
                }
                if (ttl > 0) {
                    ttlsOfInterest.add(ttl);
                }
            }
        }

        ttlsOfInterest.stream().parallel().forEach(actualTTL -> {
            Simulator.simulate(occurrences(), actualTTL, this.bestMetrics);
        });
    }

    protected void calculateMetrics() {
        if (this.occurrences.size() < 2) {
            throw new RuntimeException("Cannot calculate metrics for not reusable input");
        }
        calculateHitsPerTimeInCache();
        for (int i = 0; i < this.occurrences.size(); i++) {
            Occurrence occurrence = this.occurrences.get(i);
            Object returnValue = occurrence.getReturnValue();
            for (int j = i + 1; j < this.occurrences.size(); j++) {
                Occurrence other = this.occurrences.get(j);
                if (EqualsBuilder.reflectionEquals(returnValue, other.getReturnValue())) {
                    this.bestMetrics.addSameOccurrence(occurrence);
                    continue;
                }
                this.bestMetrics.addDifferentReturnOccurrence();
            }
        }
    }

    protected void calculateThresholds() {
        Thresholds.sumExecutionTime += this.bestMetrics.getSameOccurrencesTotalExecutionTime();
        Thresholds.executionTimes.add(this.bestMetrics.getSameOccurrencesTotalExecutionTime());

        Thresholds.sumHitRatio += this.bestMetrics.getHitRatio();
        Thresholds.hitRatios.add(this.bestMetrics.getHitRatio());

        Thresholds.sumMissRatio += this.bestMetrics.getMissRatio();
        Thresholds.missRatios.add(this.bestMetrics.getMissRatio());

        Thresholds.sumShareability += this.bestMetrics.getShareability();
        Thresholds.shareabilities.add(this.bestMetrics.getShareability());

        Thresholds.sumHitsPerTimeInCache.add(this.bestMetrics.getHitsPerTimeInCache());
        Thresholds.hitsPerTimeInCache.add(this.bestMetrics.getHitsPerTimeInCache());
    }

}