View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
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           * @return the time of the sample
31           */
32          public long getTime()
33          {
34              return time;
35          }
36  
37          /**
38           * @return the value of the sample
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 }