1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.util;
15
16
17
18
19
20
21
22 public class DefaultInvocationGate implements InvocationGate {
23
24 static final int MASK_DECREASE_RIGHT_SHIFT_COUNT = 2;
25
26
27
28
29 private static final int MAX_MASK = 0xFFFF;
30 static final int DEFAULT_MASK = 0xF;
31
32 private volatile long mask = DEFAULT_MASK;
33
34
35
36
37
38
39 private long invocationCounter = 0;
40
41
42
43
44 private static final long MASK_INCREASE_THRESHOLD = 100;
45
46
47
48
49 private static final long MASK_DECREASE_THRESHOLD = MASK_INCREASE_THRESHOLD * 8;
50
51 public DefaultInvocationGate() {
52 this(MASK_INCREASE_THRESHOLD, MASK_DECREASE_THRESHOLD, System.currentTimeMillis());
53 }
54
55 public DefaultInvocationGate(long minDelayThreshold, long maxDelayThreshold, long currentTime) {
56 this.minDelayThreshold = minDelayThreshold;
57 this.maxDelayThreshold = maxDelayThreshold;
58 this.lowerLimitForMaskMatch = currentTime + minDelayThreshold;
59 this.upperLimitForNoMaskMatch = currentTime + maxDelayThreshold;
60 }
61
62 private long minDelayThreshold;
63 private long maxDelayThreshold;
64
65 long lowerLimitForMaskMatch;
66 long upperLimitForNoMaskMatch;
67
68
69
70
71
72
73 @Override
74 final public boolean isTooSoon(long currentTime) {
75 boolean maskMatch = ((invocationCounter++) & mask) == mask;
76
77 if (maskMatch) {
78 if (currentTime < this.lowerLimitForMaskMatch) {
79 increaseMask();
80 }
81 updateLimits(currentTime);
82 } else {
83 if (currentTime > this.upperLimitForNoMaskMatch) {
84 decreaseMask();
85 updateLimits(currentTime);
86 return false;
87 }
88 }
89 return !maskMatch;
90 }
91
92 private void updateLimits(long currentTime) {
93 this.lowerLimitForMaskMatch = currentTime + minDelayThreshold;
94 this.upperLimitForNoMaskMatch = currentTime + maxDelayThreshold;
95 }
96
97
98 long getMask() {
99 return mask;
100 }
101
102 private void increaseMask() {
103 if (mask >= MAX_MASK)
104 return;
105 mask = (mask << 1) | 1;
106 }
107
108 private void decreaseMask() {
109 mask = mask >>> MASK_DECREASE_RIGHT_SHIFT_COUNT;
110 }
111
112 public long getInvocationCounter() {
113 return invocationCounter;
114 }
115 }