com.griddynamics.jagger.util.statistics.percentiles.PercentilesProcessor.java Source code

Java tutorial

Introduction

Here is the source code for com.griddynamics.jagger.util.statistics.percentiles.PercentilesProcessor.java

Source

/*
 * Copyright (c) 2010-2012 Grid Dynamics Consulting Services, Inc, All Rights Reserved
 * http://www.griddynamics.com
 *
 * This library is free software; you can redistribute it and/or modify it under the terms of
 * the GNU Lesser General Public License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.griddynamics.jagger.util.statistics.percentiles;

import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;

public class PercentilesProcessor {
    public enum EstimationStrategy {
        EXACT, HEURISTIC, AUTO
    }

    private final EstimationStrategy initialStrategy;
    private EstimationStrategy currentStrategy;

    private DescriptiveStatistics descriptiveStatistics;
    private AdaptiveHistogram adaptiveHistogram;

    private int exactProcessorMaxCapacity = 100000;

    public PercentilesProcessor() {
        this(EstimationStrategy.AUTO);
    }

    /**
     * Creates processor with the specifiedVal estimation strategy. See {@link EstimationStrategy}
     * If it is expected that samples count will be large (100M or more)
     * then {@link EstimationStrategy#HEURISTIC} should be used. In other cases {@link EstimationStrategy#AUTO}
     * should be used. {@link EstimationStrategy#EXACT} typically should not be used.
     */
    public PercentilesProcessor(EstimationStrategy estimationStrategy) {
        initialStrategy = estimationStrategy;
        reset();
    }

    public void addValue(double value) {
        switch (currentStrategy) {
        case HEURISTIC:
            adaptiveHistogram.addValue(value);
            break;
        case EXACT:
            descriptiveStatistics.addValue(value);
            break;
        case AUTO:
            if (descriptiveStatistics.getN() >= exactProcessorMaxCapacity) {
                adaptiveHistogram = new AdaptiveHistogram();
                double[] values = descriptiveStatistics.getValues();
                for (int i = 0; i < values.length; i++) {
                    adaptiveHistogram.addValue(values[i]);
                }
                adaptiveHistogram.addValue(value);
                currentStrategy = EstimationStrategy.HEURISTIC;
            } else {
                descriptiveStatistics.addValue(value);
            }
        }
    }

    public double getPercentile(double p) {
        double result = 0;
        switch (currentStrategy) {
        case HEURISTIC:
            result = adaptiveHistogram.getValueForPercentile(p);
            break;
        case AUTO:
        case EXACT:
            result = descriptiveStatistics.getPercentile(p);
        }

        return result;
    }

    public void reset() {
        currentStrategy = initialStrategy;

        switch (currentStrategy) {
        case HEURISTIC:
            adaptiveHistogram = new AdaptiveHistogram();
            break;
        case AUTO:
        case EXACT:
            descriptiveStatistics = new DescriptiveStatistics();
        }
    }

    public void setExactProcessorMaxCapacity(int capacity) {
        this.exactProcessorMaxCapacity = capacity;
    }
}