1
2
3
4
5
6
7 package org.mule.util.counters.impl;
8
9 import org.mule.util.counters.CounterFactory.Type;
10
11 import java.security.InvalidParameterException;
12 import java.util.Iterator;
13 import java.util.LinkedList;
14
15 public class RatePerUnit extends AggregateCounter
16 {
17
18 private static class Sample
19 {
20 private double value;
21 private long time;
22
23 public Sample(double value, long time)
24 {
25 this.value = value;
26 this.time = time;
27 }
28
29
30
31
32 public long getTime()
33 {
34 return time;
35 }
36
37
38
39
40 public double getValue()
41 {
42 return value;
43 }
44 }
45
46 private final LinkedList samples;
47 private final long unit;
48 private final long length;
49 private final long baseTime;
50
51 public RatePerUnit(String name, String p, Type type, AbstractCounter base)
52 {
53 super(name, type, base);
54
55 if (type == Type.RATE_PER_SECOND)
56 {
57 unit = 1000;
58 }
59 else if (type == Type.RATE_PER_MINUTE)
60 {
61 unit = 60 * 1000;
62 }
63 else if (type == Type.RATE_PER_HOUR)
64 {
65 unit = 60 * 60 * 1000;
66 }
67 else
68 {
69 throw new InvalidParameterException();
70 }
71
72 long newLength = 0;
73
74 try
75 {
76 newLength = Long.parseLong(p);
77 }
78 catch (Exception e)
79 {
80 newLength = 0;
81 }
82 finally
83 {
84 if (newLength <= 0)
85 {
86 newLength = 128;
87 }
88
89 length = newLength;
90 }
91
92 samples = new LinkedList();
93 baseTime = System.currentTimeMillis();
94 }
95
96 public double nextValue()
97 {
98 if (samples.isEmpty())
99 {
100 return 0.0;
101 }
102 else
103 {
104 double total = 0.0;
105 long current = getTime();
106 Iterator it = samples.iterator();
107 Sample sample = null;
108 while (it.hasNext())
109 {
110 sample = (Sample) it.next();
111 if (current - sample.time > length)
112 {
113 break;
114 }
115 total += sample.value;
116 }
117 return total / (1 + current - (sample != null ? sample.time : 0));
118 }
119 }
120
121 public void doCompute()
122 {
123 Sample l = samples.isEmpty() ? null : (Sample) samples.getFirst();
124 long t = getTime();
125 if (l == null || t > l.time)
126 {
127 Sample s = new Sample(this.getBase().nextValue(), t);
128 samples.addFirst(s);
129 }
130 else
131 {
132 l.value += getBase().nextValue();
133 }
134 while (samples.size() > length)
135 {
136 samples.removeLast();
137 }
138 }
139
140 protected long getTime()
141 {
142 return (System.currentTimeMillis() - baseTime) / unit;
143 }
144
145 }