View Javadoc

1   /***
2    *  Copyright 2003-2010 Terracotta, Inc.
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  
17  package net.sf.ehcache.util.ratestatistics;
18  
19  import java.util.concurrent.TimeUnit;
20  
21  /***
22   * Abstract rate statistic implementation.
23   * <p>
24   * Provides exponentially decaying moving average functionality to subclasses.
25   *
26   * @author Chris Dennis
27   */
28  abstract class AbstractRateStatistic implements RateStatistic {
29  
30      private final long rateAveragePeriod;
31  
32      /***
33       * Create an abstract statistic using the specified time averaging period.
34       *
35       * @param averagePeriod average period
36       * @param unit period time unit
37       */
38      AbstractRateStatistic(long averagePeriod, TimeUnit unit) {
39          this.rateAveragePeriod = unit.toNanos(averagePeriod);
40      }
41  
42      /***
43       * Returns the time averaging period in nanoseconds.
44       *
45       * @return average period
46       */
47      long getRateAveragePeriod() {
48          return rateAveragePeriod;
49      }
50  
51      /***
52       * Combines two timestamped values using a exponentially decaying weighted average.
53       *
54       * @param nowValue current value
55       * @param now current value timestamp
56       * @param thenAverage previous value
57       * @param then previous value timestamp
58       * @return weighted average
59       */
60      float iterateMovingAverage(float nowValue, long now, float thenAverage, long then) {
61          if (getRateAveragePeriod() == 0 || Float.isNaN(thenAverage)) {
62              return nowValue;
63          } else {
64              float alpha = (float) alpha(now, then);
65              return alpha * nowValue + (1 - alpha) * thenAverage;
66          }
67      }
68  
69      private double alpha(long now, long then) {
70          return -Math.expm1(-((double) (now - then)) / getRateAveragePeriod());
71      }
72  }