Pareto.java
Home
/
src /
main /
java /
br /
ufrgs /
inf /
prosoft /
tfcache /
Pareto.java
package br.ufrgs.inf.prosoft.tfcache;
import br.ufrgs.inf.prosoft.tfcache.configuration.Configuration;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Pareto {
private final Map<Double, Metrics> savedTimeHasMetrics;
private Metrics bestMetrics;
public Pareto() {
savedTimeHasMetrics = new ConcurrentHashMap<>();
}
public Pareto(List<Metrics> metrics) {
this();
metrics.forEach(this::addIfPareto);
}
public static void removeDominatedMetrics(Collection<Metrics> allMetrics) {
Map<Double, List<Metrics>> groupBySavedTime = allMetrics.stream().collect(Collectors.groupingBy(Metrics::getSavedTime));
groupBySavedTime.remove(0D);
groupBySavedTime.forEach((savedTime, metrics) -> {
double minIdleTime = metrics.stream().mapToDouble(Metrics::getIdleTime).min().orElse(0);
metrics.removeIf(metric -> metric.getIdleTime() > minIdleTime);
});
List<Metrics> localMaxima = groupBySavedTime.values().stream()
.map(Collection::stream)
.reduce(Stream::concat)
.orElse(Stream.empty())
.collect(Collectors.toList());
allMetrics.removeIf(metrics -> !localMaxima.contains(metrics));
}
public synchronized void addIfPareto(Metrics metrics) {
if (metrics.getSavedTime() == 0) {
return;
}
savedTimeHasMetrics.merge(metrics.getSavedTime(), metrics, (existing, incoming) -> existing.getIdleTime() < incoming.getIdleTime() ? existing : incoming);
}
public Collection<Metrics> values() {
return savedTimeHasMetrics.values();
}
public Set<Long> getTtls() {
return values().stream().map(Metrics::getTtl).collect(Collectors.toSet());
}
public Stream<Metrics> getNormalised() {
double minSavedTime = values().stream().mapToDouble(Metrics::getSavedTime).min().orElseThrow();
double maxSavedTime = values().stream().mapToDouble(Metrics::getSavedTime).max().orElseThrow();
double distanceSavedTime = maxSavedTime - minSavedTime;
double minIdleTime = values().stream().mapToDouble(Metrics::getIdleTime).min().orElseThrow();
double maxIdleTime = values().stream().mapToDouble(Metrics::getIdleTime).max().orElseThrow();
double distanceIdleTime = maxIdleTime - minIdleTime;
return values().stream().map(it -> {
double normalisedSavedTime = (it.getSavedTime() - minSavedTime) / distanceSavedTime;
double normalisedIdleTime = (it.getIdleTime() - minIdleTime) / distanceIdleTime;
return it.getNormalised(normalisedSavedTime, normalisedIdleTime);
});
}
public Metrics getBestMetrics() {
if (this.bestMetrics == null) this.bestMetrics = getBestMetrics(Configuration.getPreferences().get(0), Configuration.getPreferences().get(1));
return this.bestMetrics;
}
private Metrics getBestMetrics(double percentageObjectiveSavedTime, double percentageObjectiveIdleTime) {
if (percentageObjectiveSavedTime < 0 || percentageObjectiveSavedTime > 1) {
throw new RuntimeException("invalid objective saved time");
}
if (percentageObjectiveIdleTime < 0 || percentageObjectiveIdleTime > 1) {
throw new RuntimeException("invalid objective idle time");
}
if (savedTimeHasMetrics.isEmpty()) {
return new Metrics();
}
double minIdleTime = values().stream().mapToDouble(Metrics::getIdleTime).min().orElseThrow() * percentageObjectiveIdleTime;
double maxSavedTime = values().stream().mapToDouble(Metrics::getSavedTime).max().orElseThrow() * percentageObjectiveSavedTime;
return values().stream().min(Comparator.comparingDouble(it -> it.calculateEuclideanDistance(maxSavedTime, minIdleTime))).orElseThrow();
}
}