Metrics.java

187 lines | 5.84 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.Occurrence;

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author romulo
 */
public class Metrics implements Comparable<Metrics> {

    private long ttl;
    private long hits;
    private long timeInCache;
    private long computationTime;
    private long stales;
    private double savedTime;

    private transient String uuid;
    private transient Double idleTime;

    protected Metrics() {
        Logger.getLogger(Metrics.class.getName()).log(Level.FINEST, "returning empty metrics");
    }

    public Metrics(long ttl, long hits, long timeInCache, long computationTime, long stales, double savedTime, String uuid) {
        this(ttl, hits, timeInCache, computationTime, stales, savedTime);
        this.uuid = uuid;
    }

    public Metrics(long ttl, long hits, long timeInCache, long computationTime, long stales, double savedTime) {
        if (ttl < 0 || hits < 0 || timeInCache < 0 || computationTime < 0 || stales < 0 || savedTime < 0) {
            throw new RuntimeException("Metrics cannot be under zero."
                    + " TTL: " + ttl
                    + " hits: " + hits
                    + " timeInCache: " + timeInCache
                    + " computationTime: " + computationTime
                    + " stales: " + stales
                    + " savedTime: " + savedTime);
        }
        if (ttl == 0 || computationTime == 0 || timeInCache == 0) {
            throw new RuntimeException("Metrics cannot be zero."
                    + " TTL: " + ttl
                    + " timeInCache: " + timeInCache
                    + " computationTime: " + computationTime);
        }
        this.ttl = ttl;
        this.hits = hits;
        this.timeInCache = timeInCache;
        this.computationTime = computationTime;
        this.stales = stales;
        this.savedTime = savedTime;
    }

    public static String getUUID(Stream<Occurrence> occurrences) {
        return occurrences.map(it -> it.getStartTime() + ":" + it.getEndTime()).collect(Collectors.joining(","));
    }

    private static double calculateEuclideanDistance(double x1, double y1, double x2, double y2) {
        return Math.sqrt(Math.pow(x1 - x2, 2) - Math.pow(y1, y2));
    }

    protected double calculateEuclideanDistance(double objectiveSavedTime, double objectiveIdleTime) {
        return calculateEuclideanDistance(getSavedTime(), getIdleTime(), objectiveSavedTime, objectiveIdleTime);
    }

    protected String getUUID() {
        return uuid;
    }

    public long getTtl() {
        return this.ttl;
    }

    public long getHits() {
        return this.hits;
    }

    public long getTimeInCache() {
        return timeInCache;
    }

    public double getIdleTime() {
        if (this.idleTime == null) {
            this.idleTime = (double) timeInCache - hits;
        }
        return this.idleTime;
    }

    public long getComputationTime() {
        return computationTime;
    }

    public long getStales() {
        return this.stales;
    }

    public double getSavedTime() {
        return this.savedTime;
    }

    public BigDecimal getSavedTimePerTimeInCache() {
        if (this.timeInCache + this.computationTime == 0) {
            return BigDecimal.ZERO;
        }
        return new BigDecimal(this.savedTime)
                .divide(new BigDecimal(this.timeInCache + this.computationTime), MathContext.DECIMAL128);
    }

    public Double getDifference() {
        return Configuration.getPreferences().get(0) * getSavedTime() - Configuration.getPreferences().get(1) * getIdleTime();
    }

    protected Metrics getNormalised(double savedTime, double idleTime) {
        if (savedTime < 0 || savedTime > 1) {
            throw new RuntimeException("wrong savedTime");
        }
        if (idleTime < 0 || idleTime > 1) {
            throw new RuntimeException("wrong idleTime");
        }
        Metrics metrics = new Metrics(ttl,
                hits,
                timeInCache,
                computationTime,
                stales,
                savedTime,
                uuid);
        metrics.idleTime = idleTime;
        return metrics;
    }

    @Override
    public int compareTo(Metrics other) {
        if (getTtl() == other.getTtl()) {
            return 0;
        }
        if (getSavedTime() == other.getSavedTime() && getIdleTime() == other.getIdleTime()) {
            throw new RuntimeException("different ttls leading to same metrics");
        }
        if (getSavedTime() >= other.getSavedTime() && getIdleTime() <= other.getIdleTime()) {
            return 1;
        }
        if (getSavedTime() <= other.getSavedTime() && getIdleTime() >= other.getIdleTime()) {
            return -1;
        }
        throw new RuntimeException("comparing pareto metrics");
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 97 * hash + (int) (this.ttl ^ (this.ttl >>> 32));
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Metrics)) {
            return false;
        }
        return compareTo((Metrics) obj) == 0;
    }

    @Override
    public String toString() {
        return "TTL: " + this.ttl
                + " STpTiC: " + getSavedTimePerTimeInCache()
                + " Stales: " + this.stales
                + " Hits: " + this.hits
                + " SavedTime: " + this.savedTime
                + " TimeInCache: " + this.timeInCache
                + " ComputationTime: " + this.computationTime;
    }

}