File tree Expand file tree Collapse file tree 3 files changed +67
-4
lines changed
main/java/com/codahale/metrics
test/java/com/codahale/metrics Expand file tree Collapse file tree 3 files changed +67
-4
lines changed Original file line number Diff line number Diff line change @@ -81,6 +81,14 @@ public void update(long n) {
81
81
uncounted .add (n );
82
82
}
83
83
84
+ /**
85
+ * Set the rate to the smallest possible positive value. Used to avoid calling tick a large number of times.
86
+ */
87
+ public void reset () {
88
+ uncounted .reset ();
89
+ rate = Double .MIN_NORMAL ;
90
+ }
91
+
84
92
/**
85
93
* Mark the passage of time and decay the current rate accordingly.
86
94
*/
Original file line number Diff line number Diff line change 11
11
*/
12
12
public class ExponentialMovingAverages implements MovingAverages {
13
13
14
+ /**
15
+ * If ticking would reduce even Long.MAX_VALUE in the 15 minute EWMA below this target then don't bother
16
+ * ticking in a loop and instead reset all the EWMAs.
17
+ */
18
+ private static final double maxTickZeroTarget = 0.0001 ;
19
+ private static final int maxTicks ;
14
20
private static final long TICK_INTERVAL = TimeUnit .SECONDS .toNanos (5 );
15
21
22
+ static
23
+ {
24
+ int m3Ticks = 1 ;
25
+ final EWMA m3 = EWMA .fifteenMinuteEWMA ();
26
+ m3 .update (Long .MAX_VALUE );
27
+ do
28
+ {
29
+ m3 .tick ();
30
+ m3Ticks ++;
31
+ }
32
+ while (m3 .getRate (TimeUnit .SECONDS ) > maxTickZeroTarget );
33
+ maxTicks = m3Ticks ;
34
+ }
35
+
16
36
private final EWMA m1Rate = EWMA .oneMinuteEWMA ();
17
37
private final EWMA m5Rate = EWMA .fiveMinuteEWMA ();
18
38
private final EWMA m15Rate = EWMA .fifteenMinuteEWMA ();
@@ -51,10 +71,19 @@ public void tickIfNecessary() {
51
71
final long newIntervalStartTick = newTick - age % TICK_INTERVAL ;
52
72
if (lastTick .compareAndSet (oldTick , newIntervalStartTick )) {
53
73
final long requiredTicks = age / TICK_INTERVAL ;
54
- for (long i = 0 ; i < requiredTicks ; i ++) {
55
- m1Rate .tick ();
56
- m5Rate .tick ();
57
- m15Rate .tick ();
74
+ if (requiredTicks >= maxTicks ) {
75
+ m1Rate .reset ();
76
+ m5Rate .reset ();
77
+ m15Rate .reset ();
78
+ }
79
+ else
80
+ {
81
+ for (long i = 0 ; i < requiredTicks ; i ++)
82
+ {
83
+ m1Rate .tick ();
84
+ m5Rate .tick ();
85
+ m15Rate .tick ();
86
+ }
58
87
}
59
88
}
60
89
}
Original file line number Diff line number Diff line change
1
+ package com .codahale .metrics ;
2
+
3
+ import java .util .concurrent .TimeUnit ;
4
+
5
+ import org .junit .Test ;
6
+
7
+ import static org .junit .Assert .assertEquals ;
8
+ import static org .mockito .Mockito .mock ;
9
+ import static org .mockito .Mockito .when ;
10
+
11
+ public class ExponentialMovingAveragesTest
12
+ {
13
+ @ Test
14
+ public void testMaxTicks ()
15
+ {
16
+ final Clock clock = mock (Clock .class );
17
+ when (clock .getTick ()).thenReturn (0L , Long .MAX_VALUE );
18
+ final ExponentialMovingAverages ema = new ExponentialMovingAverages (clock );
19
+ ema .update (Long .MAX_VALUE );
20
+ ema .tickIfNecessary ();
21
+ final long secondNanos = TimeUnit .SECONDS .toNanos (1 );
22
+ assertEquals (ema .getM1Rate (), Double .MIN_NORMAL * secondNanos , 0.0 );
23
+ assertEquals (ema .getM5Rate (), Double .MIN_NORMAL * secondNanos , 0.0 );
24
+ assertEquals (ema .getM15Rate (), Double .MIN_NORMAL * secondNanos , 0.0 );
25
+ }
26
+ }
You can’t perform that action at this time.
0 commit comments