package se.l4.vibe.probes; /** * Probe that provides a ratio between two values. * * @author Andreas Holstenson * */ public class Ratio { private Ratio() { } /** * Create a new ratio between the two probes. * * <p> * Note that the ratio will call {@link SampledProbe#sample()}, which means * that the probes used should not be used as part of a {@link Sampler}. * * @param probe1 * @param probe2 * @return */ public static SampledProbe<Double> between( SampledProbe<? extends Number> a, SampledProbe<? extends Number> b) { return new SampledRatio(a, b); } /** * Create a ratio between a probe and a static value. * * <p> * Note that the ratio will call {@link SampledProbe#sample()}, which means * that the probes used should not be used as part of a {@link Sampler}. * * @param probe1 * @param number * @return */ public static SampledProbe<Double> between( SampledProbe<? extends Number> a, double b) { return new SampledRatio(a, new ConstantProbe<Double>(b)); } /** * Create a ratio between a static value and a probe. * * <p> * Note that the ratio will call {@link SampledProbe#sample()}, which means * that the probes used should not be used as part of a {@link Sampler}. * * @param number * @param probe2 * @return */ public static SampledProbe<Double> between( double a, SampledProbe<? extends Number> b) { return new SampledRatio(new ConstantProbe<Double>(a), b); } /** * Create a new ratio between the two probes. * * @param probe1 * @param probe2 * @return */ public static Probe<Double> between( Probe<? extends Number> a, Probe<? extends Number> b) { return new NormalRatio(a, b); } /** * Create a ratio between a probe and a static value. * * @param probe1 * @param number * @return */ public static Probe<Double> between( Probe<? extends Number> a, double b) { return new NormalRatio(a, new ConstantProbe<Double>(b)); } /** * Create a ratio between a static value and a probe. * * @param number * @param probe2 * @return */ public static Probe<Double> between( double a, Probe<? extends Number> b) { return new NormalRatio(new ConstantProbe<Double>(a), b); } private static class SampledRatio extends AbstractSampledProbe<Double> { private final SampledProbe<? extends Number> probe1; private final SampledProbe<? extends Number> probe2; public SampledRatio(SampledProbe<? extends Number> probe1, SampledProbe<? extends Number> probe2) { this.probe1 = probe1; this.probe2 = probe2; } @Override public Double peek() { return probe1.peek().doubleValue() / probe2.peek().doubleValue(); } @Override protected Double sample0() { return probe1.sample().doubleValue() / probe2.sample().doubleValue(); } } private static class NormalRatio implements Probe<Double> { private final Probe<? extends Number> probe1; private final Probe<? extends Number> probe2; public NormalRatio(Probe<? extends Number> probe1, Probe<? extends Number> probe2) { this.probe1 = probe1; this.probe2 = probe2; } @Override public Double read() { return probe1.read().doubleValue() / probe2.read().doubleValue(); } } }