Metrics.java

158 lines | 4.909 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.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

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

  private static final Logger LOGGER = Logger.getLogger(Metrics.class.getName());
  private long ttl;
  private long hits;
  private long timeInCache;
  private long computationTime;
  private long stales;
  private long savedTime;

  private transient Long idleTime;
  private transient String uuid;

  protected Metrics() {
    LOGGER.finest("returning empty metrics");
  }

  public Metrics(long ttl, long hits, long timeInCache, long computationTime, long stales, long 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, long 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(","));
  }

  public static BigDecimal calculateEuclideanDistance(double x1, double y1, double x2, double y2) {
    return BigDecimal.valueOf(x1 - x2).pow(2).add(BigDecimal.valueOf(y1 - y2).pow(2)).sqrt(MathContext.DECIMAL128);
  }

  public static BigDecimal calculateEuclideanDistance(BigDecimal x1, BigDecimal y1, double x2, double y2) {
    return x1.subtract(BigDecimal.valueOf(x2)).pow(2)
      .add(y1.subtract(BigDecimal.valueOf(y2)).pow(2))
      .sqrt(MathContext.DECIMAL128);
  }

  protected BigDecimal 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 long getIdleTime() {
    if (this.idleTime == null) this.idleTime = timeInCache - hits;
    return this.idleTime;
  }

  public long getComputationTime() {
    return computationTime;
  }

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

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

  public BigDecimal getSavedTimePerTimeInCache() {
    if (this.timeInCache + this.computationTime == 0) return BigDecimal.ZERO;
    return BigDecimal.valueOf(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();
  }

  @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
      + " SavedTime: " + this.savedTime
      + " Hits: " + this.hits
      + " ComputationTime: " + this.computationTime
      + " TimeInCache: " + this.timeInCache
      + " Stales: " + this.stales;
  }

}