package se.l4.vibe.probes;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import se.l4.vibe.probes.Sampler.Entry;
/**
* Probes that will calculate the sum of other {@link Probe probes} and
* {@link Sampler time series}.
*
* @author Andreas Holstenson
*
*/
public class Sum
{
private Sum()
{
}
/**
* Create a probe that will calculate the sum of the entire series as a
* {@link Long}.
*
* @param series
* @return
*/
public static <T extends Number> Probe<Long> forSamplerAsLong(Sampler<T> series)
{
return SamplerProbes.forSampler(series, new SumLongOperation<T, T>(ValueReaders.<T>same()));
}
/**
* Create a probe that will calculate the sum of the entire series as a
* {@link Long}.
*
* @param series
* @return
*/
public static <T, N extends Number> Probe<Long> forSamplerAsLong(Sampler<T> series, ValueReader<T, N> reader)
{
return SamplerProbes.forSampler(series, new SumLongOperation<T, N>(reader));
}
/**
* Create a probe that will calculate the sum of the entire series as a
* {@link Double}.
*
* @param series
* @return
*/
public static <T extends Number> Probe<Double> forSamplerAsDouble(Sampler<T> series)
{
return SamplerProbes.forSampler(series, new SumDoubleOperation<T, T>(ValueReaders.<T>same()));
}
/**
* Create a probe that will calculate the sum of the entire series as a
* {@link Double}.
*
* @param series
* @return
*/
public static <T, N extends Number> Probe<Double> forSamplerAsDouble(Sampler<T> series, ValueReader<T, N> reader)
{
return SamplerProbes.forSampler(series, new SumDoubleOperation<T, N>(reader));
}
/**
* Create a probe that will calculate the sum as a sliding window with
* the specified duration.
*
* @param series
* @param duration
* @param unit
* @return
*/
public static <T extends Number> Probe<Long> forSamplerAsLong(
Sampler<T> series,
long duration,
TimeUnit unit
)
{
return SamplerProbes.forSampler(series, duration, unit, new SumLongOperation<T, T>(ValueReaders.<T>same()));
}
/**
* Create a probe that will calculate the sum as a sliding window with
* the specified duration.
*
* @param series
* @param duration
* @param unit
* @return
*/
public static <T, N extends Number> Probe<Long> forSamplerAsLong(
Sampler<T> series,
ValueReader<T, N> reader,
long duration,
TimeUnit unit
)
{
return SamplerProbes.forSampler(series, duration, unit, new SumLongOperation<T, N>(reader));
}
/**
* Create a probe that will calculate the sum as a sliding window with
* the specified duration.
*
* @param series
* @param duration
* @param unit
* @return
*/
public static <T extends Number> Probe<Double> forSamplerAsDouble(
Sampler<T> series,
long duration,
TimeUnit unit
)
{
return SamplerProbes.forSampler(series, duration, unit, new SumDoubleOperation<T, T>(ValueReaders.<T>same()));
}
/**
* Create a probe that will calculate the sum as a sliding window with
* the specified duration.
*
* @param series
* @param duration
* @param unit
* @return
*/
public static <T, N extends Number> Probe<Double> forSamplerAsDouble(
Sampler<T> series,
ValueReader<T, N> reader,
long duration,
TimeUnit unit
)
{
return SamplerProbes.forSampler(series, duration, unit, new SumDoubleOperation<T, N>(reader));
}
private static class SumDoubleOperation<T, N extends Number>
implements SampleOperation<T, Double>
{
private final ValueReader<T, N> reader;
private double sum;
public SumDoubleOperation(ValueReader<T, N> reader)
{
this.reader = reader;
}
@Override
public void remove(T value, Collection<Entry<T>> entries)
{
sum -= reader.read(value).doubleValue();
}
@Override
public void add(T value, Collection<Entry<T>> entries)
{
sum += reader.read(value).doubleValue();
}
@Override
public Double get()
{
return sum;
}
}
private static class SumLongOperation<T, N extends Number>
implements SampleOperation<T, Long>
{
private final ValueReader<T, N> reader;
private long sum;
public SumLongOperation(ValueReader<T, N> reader)
{
this.reader = reader;
}
@Override
public void remove(T value, Collection<Entry<T>> entries)
{
sum -= reader.read(value).longValue();
}
@Override
public void add(T value, Collection<Entry<T>> entries)
{
sum += reader.read(value).longValue();
}
@Override
public Long get()
{
return sum;
}
}
}