/**
   Copyright [2013] [Mushroom]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
/**
 Notice : this source is extracted from Hadoop metric2 package
 and some source code may changed by zavakid
 */
package com.zavakid.mushroom.util;

/**
 * Helper to compute running sample stats
 * 
 * @author Hadoop metric2 package's authors
 * @since 0.1
 */
public class SampleStat {

    private final MinMax minmax     = new MinMax();
    private long         numSamples = 0;
    private double       a0, a1, s0, s1;

    /**
     * Construct a new running sample stat
     */
    public SampleStat(){
        a0 = s0 = 0.0;
    }

    public void reset() {
        numSamples = 0;
        a0 = s0 = 0.0;
        minmax.reset();
    }

    // We want to reuse the object, sometimes.
    void reset(long numSamples, double a0, double a1, double s0, double s1, MinMax minmax) {
        this.numSamples = numSamples;
        this.a0 = a0;
        this.a1 = a1;
        this.s0 = s0;
        this.s1 = s1;
        this.minmax.reset(minmax);
    }

    /**
     * Copy the values to other (saves object creation and gc.)
     * 
     * @param other the destination to hold our values
     */
    public void copyTo(SampleStat other) {
        other.reset(numSamples, a0, a1, s0, s1, minmax);
    }

    /**
     * Add a sample the running stat.
     * 
     * @param x the sample number
     * @return self
     */
    public SampleStat add(double x) {
        minmax.add(x);
        return add(1, x);
    }

    /**
     * Add some sample and a partial sum to the running stat. Note, min/max is not evaluated using this method.
     * 
     * @param nSamples number of samples
     * @param x the partial sum
     * @return self
     */
    public SampleStat add(long nSamples, double x) {
        numSamples += nSamples;

        if (numSamples == 1) {
            a0 = a1 = x;
            s0 = 0.0;
        } else {
            // The Welford method for numerical stability
            a1 = a0 + (x - a0) / numSamples;
            s1 = s0 + (x - a0) * (x - a1);
            a0 = a1;
            s0 = s1;
        }
        return this;
    }

    /**
     * @return the total number of samples
     */
    public long numSamples() {
        return numSamples;
    }

    /**
     * @return the arithmetic mean of the samples
     */
    public double mean() {
        return numSamples > 0 ? a1 : 0.0;
    }

    /**
     * @return the variance of the samples
     */
    public double variance() {
        return numSamples > 1 ? s1 / (numSamples - 1) : 0.0;
    }

    /**
     * @return the standard deviation of the samples
     */
    public double stddev() {
        return Math.sqrt(variance());
    }

    /**
     * @return the minimum value of the samples
     */
    public double min() {
        return minmax.min();
    }

    /**
     * @return the maximum value of the samples
     */
    public double max() {
        return minmax.max();
    }

    /**
     * Helper to keep running min/max
     */
    @SuppressWarnings("PublicInnerClass")
    public static class MinMax {

        // Float.MAX_VALUE is used rather than Double.MAX_VALUE, even though the
        // min and max variables are of type double.
        // Float.MAX_VALUE is big enough, and using Double.MAX_VALUE makes 
        // Ganglia core due to buffer overflow.
        // The same reasoning applies to the MIN_VALUE counterparts.
        public static final double DEFAULT_MIN_VALUE = Float.MAX_VALUE;
        public static final double DEFAULT_MAX_VALUE = Float.MIN_VALUE;

        private double             min               = DEFAULT_MIN_VALUE;
        private double             max               = DEFAULT_MAX_VALUE;

        public void add(double value) {
            if (value > max) max = value;
            if (value < min) min = value;
        }

        public double min() {
            return min;
        }

        public double max() {
            return max;
        }

        public void reset() {
            min = DEFAULT_MIN_VALUE;
            max = DEFAULT_MAX_VALUE;
        }

        public void reset(MinMax other) {
            min = other.min();
            max = other.max();
        }

    }

}

@@ -3509,50 +3509,8 @@
  */%0A
-    @SuppressWarnings(%22PublicInnerClass%22)%0A
     

remove noneused annatation