Thresholds.java

221 lines | 7.287 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 double sumMissRatio;
    public static double sumHitRatio;
    public static double sumExecutionTime;
    public static double sumShareability;
    public static BigDecimal sumHitsPerTimeInCache;

    public static BigDecimal averageHitsPerTimeInCache;

    public static Double stdDevHitRatio;
    public static Double stdDevMissRatio;
    public static Double stdDevExecutionTimeRatio;
    public static BigDecimal stdDevHitsPerTimeInCache;
    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> hitsPerTimeInCache = new ArrayList<>();

    public static void reset() {
        Thresholds.sumMissRatio = 0;
        Thresholds.sumHitRatio = 0;
        Thresholds.sumExecutionTime = 0;
        Thresholds.sumShareability = 0;
        Thresholds.sumHitsPerTimeInCache = new BigDecimal(BigInteger.ZERO);

        Thresholds.averageHitsPerTimeInCache = null;

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

        Thresholds.population = 0;

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

    /**
     * General mean hit ratio of all calls
     *
     * @return
     */
    public static double getAverageHitRatio() {
        if (population == 0) {
            return 0;
        }
        return new BigDecimal(sumHitRatio).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
    }

    public static double getAverageMissRatio() {
        if (population == 0) {
            return 0;
        }
        return new BigDecimal(sumMissRatio).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
    }

    public static double getAverageExecutionTime() {
        if (population == 0) {
            return 0;
        }
        return new BigDecimal(sumExecutionTime).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
    }

    public static double getAverageShareability() {
        if (population == 0) {
            return 0;
        }
        return new BigDecimal(sumShareability).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 getStdDevHitsPerTimeInCache() {
        if (population == 0) {
            return new BigDecimal(BigInteger.ZERO);
        }
        if (stdDevHitsPerTimeInCache != null) {
            return stdDevHitsPerTimeInCache;
        }

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

    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 getAverageHitsPerTimeInCache() {
        if (hitsPerTimeInCache.isEmpty()) {
            return new BigDecimal(BigInteger.ZERO);
        }
        if (averageHitsPerTimeInCache != null) {
            return averageHitsPerTimeInCache;
        }

        averageHitsPerTimeInCache = sumHitsPerTimeInCache.divide(new BigDecimal(hitsPerTimeInCache.size()), 5, RoundingMode.HALF_UP);
        return averageHitsPerTimeInCache;
    }

//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 hitsPerTimeInCacheThreshold(int kStdDev) {
        return getAverageHitsPerTimeInCache().add(getStdDevHitsPerTimeInCache().multiply(new BigDecimal(kStdDev)));
    }

}