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

se.l4.vibe.probes.Average Maven / Gradle / Ivy

There is a newer version: 0.4.0
Show newest version
package se.l4.vibe.probes;

import java.util.Collection;
import java.util.concurrent.TimeUnit;

/**
 * Probes for creating average values.
 * 
 * @author Andreas Holstenson
 *
 */
public class Average
{
	private Average()
	{
	}
	
	/**
	 * Create an average for the entire time series.
	 * 
	 * @param series
	 * @return
	 */
	public static  Probe forSampler(Sampler series)
	{
		return SamplerProbes.forSampler(series, Average.newOperation());
	}
	
	/**
	 * Create an average for the entire time series.
	 * 
	 * @param series
	 * @param reader
	 * @return
	 */
	public static  Probe forSampler(Sampler series, ValueReader reader)
	{
		return SamplerProbes.forSampler(series, Average.newOperation(reader));
	}
	
	/**
	 * Create an average for a time series that will keep an average for the
	 * specified duration.
	 * 
	 * @param series
	 * @param duration
	 * @param unit
	 * @return
	 */
	public static  Probe forSampler(
			Sampler series,
			long duration,
			TimeUnit unit)
	{
		return SamplerProbes.forSampler(series, duration, unit, Average.newOperation());
	}
	
	/**
	 * Create an average for a time series that will keep an average for the
	 * specified duration.
	 * 
	 * @param series
	 * @param duration
	 * @param unit
	 * @return
	 */
	public static  Probe forSampler(
			Sampler series,
			ValueReader reader,
			long duration,
			TimeUnit unit)
	{
		return SamplerProbes.forSampler(series, duration, unit, Average.newOperation(reader));
	}
	
	/**
	 * Create a probe that will average another sampled probe. This type of
	 * probe should be used as part of a {@link Sampler time series}.
	 * 
	 * @param probe
	 * @return
	 */
	public static  SampledProbe forProbe(
			SampledProbe probe)
	{
		return new AveragingProbeProbe(probe);
	}
	
	/**
	 * Create a probe that averages numeric values.
	 * 
	 * @return
	 */
	public static AveragingProbe create()
	{
		return new AveragingProbe();
	}
	
	/**
	 * Create an operation that will calculate an average.
	 * 
	 * @return
	 */
	public static  SampleOperation newOperation()
	{
		return new AverageOperation(ValueReaders.same());
	}
	
	/**
	 * Create an operation that will calculate an average.
	 * 
	 * @return
	 */
	public static  SampleOperation newOperation(ValueReader reader)
	{
		return new AverageOperation(reader);
	}
	
	/**
	 * Operation that will calculate the average.
	 * 
	 * @author Andreas Holstenson
	 *
	 * @param 
	 */
	private static class AverageOperation
		implements SampleOperation
	{
		private final ValueReader reader;
		
		private double totalSum;
		private double totalEntries;
		
		public AverageOperation(ValueReader reader)
		{
			this.reader = reader;
		}
		
		@Override
		public void add(I value, Collection> entries)
		{
			totalSum += reader.read(value).doubleValue();
			totalEntries += 1;
		}

		@Override
		public void remove(I value, Collection> entries)
		{
			totalSum -= reader.read(value).doubleValue();
			totalEntries -= 1;
		}
		
		@Override
		public Double get()
		{
			return totalSum / totalEntries;
		}
	}
	
	/**
	 * Probe that calculates the average of another probe.
	 * 
	 * @author Andreas Holstenson
	 *
	 * @param 
	 */
	private static class AveragingProbeProbe
		extends AbstractSampledProbe
	{
		private long accumulated;
		private long samples;
		private final SampledProbe probe;

		public AveragingProbeProbe(SampledProbe probe)
		{
			this.probe = probe;
		}

		@Override
		public Double peek()
		{
			long diff = probe.peek().longValue();
			return (accumulated + diff) / (samples + 1.0);
		}

		@Override
		protected Double sample0()
		{
			accumulated += probe.read().longValue(); 
			samples++;
			return accumulated / (double) samples;
		}

	}
}