/** * 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. */ package org.apache.aurora.common.stats; import com.google.common.base.Preconditions; import com.google.common.base.Supplier; /** * Function to compute the ratio of two time series. * The first argument is the numerator, and the second is the denominator. Assumes that the * timestamps of the two arguments are suitably synchronized (i.e. the ith point in the numerator * time series corresponds with the ith point of the denominator time series). * * @author William Farner */ public class Ratio extends SampledStat<Double> { private final Supplier<Number> numeratorAccessor; private final Supplier<Number> denominatorAccessor; private Ratio(String name, Supplier<Number> numeratorAccessor, Supplier<Number> denominatorAccessor) { super(name, 0d); this.numeratorAccessor = Preconditions.checkNotNull(numeratorAccessor); this.denominatorAccessor = Preconditions.checkNotNull(denominatorAccessor); } public static <T extends Number> Ratio of(Stat<T> numerator, Stat<T> denominator) { Preconditions.checkNotNull(numerator); Preconditions.checkNotNull(denominator); String name = String.format("%s_per_%s", numerator.getName(), denominator.getName()); return Ratio.of(name, numerator, denominator); } public static <T extends Number> Ratio of(String name, final Stat<T> numerator, final Stat<T> denominator) { Preconditions.checkNotNull(numerator); Preconditions.checkNotNull(denominator); Stats.export(numerator); Stats.export(denominator); return new Ratio(name, numerator::read, denominator::read); } public static Ratio of(String name, final Number numerator, final Number denominator) { Preconditions.checkNotNull(numerator); Preconditions.checkNotNull(denominator); return new Ratio(name, () -> numerator, () -> denominator); } @Override public Double doSample() { double numeratorValue = numeratorAccessor.get().doubleValue(); double denominatorValue = denominatorAccessor.get().doubleValue(); if ((denominatorValue == 0) || (denominatorValue == Double.NaN) || (numeratorValue == Double.NaN)) { return 0d; } return numeratorValue / denominatorValue; } }