All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.util.concurrent.MovingAverageTask Maven / Gradle / Ivy

package com.bigdata.util.concurrent;

import java.util.concurrent.Callable;

import org.apache.log4j.Logger;

/**
 * Class tracks a the moving average of some sampled datum.
 * 
 * @author Bryan Thompson
 * @version $Id$
 */
public class MovingAverageTask implements Runnable {

    protected static final Logger log = Logger
            .getLogger(MovingAverageTask.class);

    /**
     * The label used in log messages.
     */
    protected final String name;

    /**
     * Used to sample whatever is being measured.
     */
    protected final Callable sampleTask;
    
    /**
     * The weight used to compute the moving average.
     */
    protected final double w;

    /**
     * #of samples taken so far.
     */
    protected long nsamples = 0;

    /**
     * The moving average.
     */
    protected double average = 0d;

    /**
     * The current value of the moving average.
     */
    public double getMovingAverage() {
       
        return average;
        
    }

//    /**
//     * Scaling factor converts nanoseconds to milliseconds.
//     */
//    static protected final double scalingFactor = 1d / TimeUnit.NANOSECONDS
//            .convert(1, TimeUnit.MILLISECONDS);

    /**
     * The weight used to compute the moving average.
     */
    public double getWeight() {

        return w;

    }

    /**
     * #of samples taken so far.
     */
    public long getSampleCount() {

        return nsamples;

    }

    /**
     * The recommended default weight.
     */
    public static final double DEFAULT_WEIGHT = .2d;

    /**
     * 
     * @param name
     *            The label for log messages.
     * @param sampleTask
     *            Task that returns a sampled value.
     */
    public MovingAverageTask(final String name,
            final Callable sampleTask) {

        this(name, sampleTask, DEFAULT_WEIGHT);

    }

    /**
     * Core impl.
     * 
     * @param name
     *            The label for log messages.
     * @param queue
     *            Task that returns a sampled value.
     * @param w
     *            The weight to be used by
     *            {@link #getMovingAverage(double, double, double)}
     */
    public MovingAverageTask(final String name,
            final Callable sampleTask, final double w) {

        if (name == null)
            throw new IllegalArgumentException();

        if (sampleTask == null)
            throw new IllegalArgumentException();

        if (w <= 0d || w >= 1d)
            throw new IllegalArgumentException();

        this.name = name;

        this.sampleTask = sampleTask;

        this.w = w;

    }

    /**
     * Compute a moving average: (1 - w) * avg + w * q
     * 
     * @param avg
     *            The previous average and initially zero (0.0).
     * @param q
     *            The current value (e.g., the instantaneous measurement of the
     *            #of active tasks plus the length of the queue).
     * @param w
     *            The weight for the moving average in (0:1). Values around .2
     *            seem appropriate.
     * 
     * @return The updated moving average.
     */
    final static protected double getMovingAverage(final double avg,
            final double q, final double w) {

        return (1 - w) * avg + (w * q);

    }

    /**
     * Note: don't throw anything from here or it will cause the task to no
     * longer be run!
     */
    public void run() {

        try {

            final double sample = sampleTask.call().doubleValue();

            average = getMovingAverage(average, sample, w);

            nsamples++;

        } catch (Exception ex) {

            log.warn(name, ex);

        }

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy