View Javadoc

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