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 }