Metrics.java
Home
/
src /
main /
java /
br /
ufrgs /
inf /
prosoft /
tfcache /
Metrics.java
/*
* 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 java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.util.Collection;
import java.util.List;
import java.util.Map;
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 stales;
private long savedTime;
private BigDecimal savedTimePerTimeInCache;
public Metrics() {
this.savedTimePerTimeInCache = new BigDecimal(BigInteger.ZERO);
}
public Metrics(long ttl, long hits, long timeInCache, long stales, long savedTime) {
if (ttl < 0 || hits < 0 || timeInCache < 0 || stales < 0 || savedTime < 0) {
throw new RuntimeException("Metrics cannot be under zero");
}
if (timeInCache == 0) {
throw new RuntimeException("timeInCache should not be zero");
}
this.ttl = ttl;
this.hits = hits;
this.timeInCache = timeInCache;
this.stales = stales;
this.savedTime = savedTime;
this.savedTimePerTimeInCache = new BigDecimal(this.savedTime).divide(new BigDecimal(this.timeInCache), MathContext.DECIMAL128);
}
public long getTtl() {
return this.ttl;
}
public long getHits() {
return this.hits;
}
public long getTimeInCache() {
return timeInCache;
}
public long getStales() {
return this.stales;
}
public long getSavedTime() {
return this.savedTime;
}
public BigDecimal getSavedTimePerTimeInCache() {
return this.savedTimePerTimeInCache;
}
public synchronized void keepBestMetrics(Metrics metrics) {
keepBestMetrics(metrics.ttl, metrics.hits, metrics.timeInCache, metrics.stales, metrics.savedTime);
}
public synchronized void keepBestMetrics(long ttl, long hits, long timeInCache, long stales, long savedTime) {
if (ttl < 0 || hits < 0 || timeInCache < 0 || stales < 0 || savedTime < 0) {
throw new RuntimeException("Metrics cannot be under zero. TTL: " + ttl
+ " hits: " + hits
+ " timeInCache: " + timeInCache
+ " stales: " + stales
+ " savedTime: " + savedTime);
}
if (ttl == 0 || hits == 0 || savedTime == 0) {
return;
}
if (timeInCache == 0) {
throw new RuntimeException("timeInCache should not be zero");
}
BigDecimal savedTimePerTimeInCache = new BigDecimal(savedTime).divide(new BigDecimal(timeInCache), MathContext.DECIMAL128);
if (this.ttl == 0 || compareTo(ttl, hits, timeInCache, stales, savedTime, savedTimePerTimeInCache) == -1) {
this.ttl = ttl;
this.hits = hits;
this.timeInCache = timeInCache;
this.stales = stales;
this.savedTime = savedTime;
this.savedTimePerTimeInCache = savedTimePerTimeInCache;
}
}
public static void removeDominatedMetrics(Collection<Metrics> allMetrics) {
Map<Long, List<Metrics>> groupBySavedTime = allMetrics.stream().collect(Collectors.groupingBy(Metrics::getSavedTime));
groupBySavedTime.remove(0L);
groupBySavedTime.forEach((savedTime, value) -> {
Metrics max = value.stream().max(Metrics::compareTo).get();
value.removeIf(metric -> metric.getSavedTimePerTimeInCache().compareTo(max.getSavedTimePerTimeInCache()) == -1);
});
List<Metrics> localMaxima = groupBySavedTime.entrySet().stream()
.map(entry -> entry.getValue().stream())
.reduce(Stream::concat)
.orElse(Stream.empty())
.collect(Collectors.toList());
allMetrics.removeIf(metrics -> !localMaxima.contains(metrics));
}
@Override
public int compareTo(Metrics other) {
return compareTo(other.ttl, other.hits, other.timeInCache, other.stales, other.savedTime, other.savedTimePerTimeInCache);
}
private int compareTo(long ttl, long hits, long timeInCache, long stales, long savedTime, BigDecimal savedTimePerTimeInCache) {
if (getSavedTimePerTimeInCache().compareTo(savedTimePerTimeInCache) == 1) {
return 1;
}
if (getSavedTimePerTimeInCache().compareTo(savedTimePerTimeInCache) == -1) {
return -1;
}
if (this.stales < stales) {
return 1;
}
if (this.stales > stales) {
return -1;
}
if (this.savedTime > savedTime) {
return 1;
}
if (this.savedTime < savedTime) {
return -1;
}
if (this.hits > hits) {
return 1;
}
if (this.hits < hits) {
return -1;
}
if (this.ttl < ttl) {
return 1;
}
if (this.ttl > ttl) {
return -1;
}
if (this.timeInCache < timeInCache) {
return 1;
}
if (this.timeInCache > timeInCache) {
return -1;
}
return 0;
}
@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;
}
}