Thresholds.java

210 lines | 7.2 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.metrics;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author romulo
 */
public class Thresholds {

    public static BigDecimal averageSavedTimePerTimeInCache;

    public static Double stdDevHitRatio;
    public static Double stdDevMissRatio;
    public static Double stdDevExecutionTimeRatio;
    public static BigDecimal stdDevSavedTimePerTimeInCache;
    public static Double stdDevShareability;

    public static long population;

    public static final List<Double> hitRatios = new ArrayList<>();
    public static final List<Double> missRatios = new ArrayList<>();
    public static final List<Long> executionTimes = new ArrayList<>();
    public static final List<Double> shareabilities = new ArrayList<>();
    public static final List<BigDecimal> savedTimePerTimeInCache = new ArrayList<>();

    public static void reset() {
        Thresholds.averageSavedTimePerTimeInCache = null;

        Thresholds.stdDevHitRatio = null;
        Thresholds.stdDevMissRatio = null;
        Thresholds.stdDevExecutionTimeRatio = null;
        Thresholds.stdDevSavedTimePerTimeInCache = null;
        Thresholds.stdDevShareability = null;

        Thresholds.population = 0;

        Thresholds.hitRatios.clear();
        Thresholds.missRatios.clear();
        Thresholds.executionTimes.clear();
        Thresholds.shareabilities.clear();
        Thresholds.savedTimePerTimeInCache.clear();
    }

    /**
     * General mean hit ratio of all calls
     *
     * @return
     */
    public static double getAverageHitRatio() {
        if (population == 0) {
            return 0;
        }
        return new BigDecimal(hitRatios.stream().reduce(Double::sum).orElse(0D)).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
    }

    public static double getAverageMissRatio() {
        if (population == 0) {
            return 0;
        }
        return new BigDecimal(missRatios.stream().reduce(Double::sum).orElse(0D)).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
    }

    public static double getAverageExecutionTime() {
        if (population == 0) {
            return 0;
        }
        return new BigDecimal(executionTimes.stream().reduce(Long::sum).orElse(0L)).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
    }

    public static double getAverageShareability() {
        if (population == 0) {
            return 0;
        }
        return new BigDecimal(shareabilities.stream().reduce(Double::sum).orElse(0D)).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
    }

    public static double getStdDevHitRatio() {
        if (population == 0) {
            return 0;
        }
        if (stdDevHitRatio != null) {
            return stdDevHitRatio;
        }

        double mean = getAverageHitRatio();
        double temp = hitRatios.stream()
                .map(hitRate -> (hitRate - mean) * (hitRate - mean))
                .reduce(Double::sum)
                .orElse(0D);
        stdDevHitRatio = Math.sqrt(temp / population);
        return stdDevHitRatio;
    }

    public static double getStdDevMissRatio() {
        if (population == 0) {
            return 0;
        }
        if (stdDevMissRatio != null) {
            return stdDevMissRatio;
        }

        double mean = getAverageMissRatio();
        double temp = missRatios.stream().map(missRatio -> (missRatio - mean) * (missRatio - mean))
                .reduce(Double::sum)
                .orElse(0D);
        stdDevMissRatio = Math.sqrt(temp / population);
        return stdDevMissRatio;
    }

    public static double getStdDevExecutionTimeRatio() {
        if (population == 0) {
            return 0;
        }
        if (stdDevExecutionTimeRatio != null) {
            return stdDevExecutionTimeRatio;
        }

        double mean = getAverageExecutionTime();
        double temp = executionTimes.stream()
                .map(executionTime -> (executionTime - mean) * (executionTime - mean))
                .reduce(Double::sum)
                .orElse(0D);
        stdDevExecutionTimeRatio = Math.sqrt(temp / population);
        return stdDevExecutionTimeRatio;
    }

    public static BigDecimal getStdDevSavedTimePerTimeInCache() {
        if (population == 0) {
            return new BigDecimal(BigInteger.ZERO);
        }
        if (stdDevSavedTimePerTimeInCache != null) {
            return stdDevSavedTimePerTimeInCache;
        }

        BigDecimal mean = getAverageSavedTimePerTimeInCache();
        BigDecimal temp = savedTimePerTimeInCache.stream()
                .map(frequency -> frequency.subtract(mean).multiply(frequency.subtract(mean)))
                .reduce(BigDecimal::add)
                .orElse(new BigDecimal(BigInteger.ZERO));
        stdDevSavedTimePerTimeInCache = temp.divide(new BigDecimal(population), MathContext.DECIMAL128).sqrt(MathContext.DECIMAL128);
        return stdDevSavedTimePerTimeInCache;
    }

    public static double getStdDevShareability() {
        if (population == 0) {
            return 0;
        }
        if (stdDevShareability != null) {
            return stdDevShareability;
        }

        double mean = getAverageShareability();
        double temp = shareabilities.stream()
                .map(shareability -> (shareability - mean) * (shareability - mean))
                .reduce(Double::sum)
                .orElse(0D);
        stdDevShareability = Math.sqrt(temp / population);
        return stdDevShareability;
    }

    public static BigDecimal getAverageSavedTimePerTimeInCache() {
        if (savedTimePerTimeInCache.isEmpty()) {
            return new BigDecimal(BigInteger.ZERO);
        }
        if (averageSavedTimePerTimeInCache != null) {
            return averageSavedTimePerTimeInCache;
        }

        averageSavedTimePerTimeInCache = savedTimePerTimeInCache.stream().reduce(BigDecimal::add).orElse(new BigDecimal(BigInteger.ZERO))
                .divide(new BigDecimal(savedTimePerTimeInCache.size()), MathContext.DECIMAL128);
        return averageSavedTimePerTimeInCache;
    }

//getting X% with most hits
    public static double hitThreshold(int kStdDev) {
        return getAverageHitRatio() + (kStdDev * getStdDevHitRatio());
    }

//getting X% with most misses
    public static double missThreshold(int kStdDev) {
        return getAverageMissRatio() + (kStdDev * getStdDevMissRatio());
    }

//getting X% most expensive methods
    public static double expensivenessThreshold(int kStdDev) {
        return getAverageExecutionTime() + (kStdDev * getStdDevExecutionTimeRatio());
    }

    public static double shareabilityThreshold(int kStdDev) {
        return getAverageShareability() + (kStdDev * getStdDevShareability());
    }

//getting X% most frenquent
    public static BigDecimal savedTimePerTimeInCacheThreshold(int kStdDev) {
        return getAverageSavedTimePerTimeInCache().add(getStdDevSavedTimePerTimeInCache().multiply(new BigDecimal(kStdDev)));
    }

}