KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > excalibur > event > impl > RateLimitingPredicate


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  *
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.excalibur.event.impl;
18
19 import org.apache.excalibur.event.EnqueuePredicate;
20 import org.apache.excalibur.event.Sink;
21
22 /**
23  * This enqueue predicate implements input rate policing.
24  *
25  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
26  * @version $Revision: 1.4 $
27  */

28 public class RateLimitingPredicate implements EnqueuePredicate
29 {
30     /** The rate to which the enqueuing should be limited */
31     private double m_targetRate;
32
33     /** The depth of the token bucket */
34     private int m_depth;
35
36     private int m_tokenCount;
37     private long m_lastTime;
38     private double m_regenTimeMs;
39
40     /** Number of milliseconds between regenerations */
41     private static final long MIN_REGENERATION_TIME = 0;
42
43     //------------------------- RateLimitingPredicate constructors
44
/**
45      * Create a new RateLimitingPredicate for the given sink,
46      * bucket depth and no rate limit.
47      * @since May 15, 2002
48      *
49      * @param depth
50      * The token bucket depth.
51      */

52     public RateLimitingPredicate(int depth)
53     {
54         this(-1.0, depth);
55     }
56
57     /**
58      * Create a new RateLimitingPredicate for the given sink,
59      * targetRate, and token bucket depth.
60      * A rate of <m_code>-1.0</m_code> indicates no rate limit.
61      * @since May 15, 2002
62      *
63      * @param targetRate
64      * The rate that is the target for this predicate
65      * @param depth
66      * The token bucket depth.
67      */

68     public RateLimitingPredicate(double targetRate, int depth)
69     {
70         m_targetRate = targetRate;
71         m_depth = depth;
72
73         m_regenTimeMs = (1.0 / targetRate) * 1.0e3;
74         if (m_regenTimeMs < 1)
75         {
76             m_regenTimeMs = 1;
77         }
78
79         m_tokenCount = depth;
80         m_lastTime = System.currentTimeMillis();
81     }
82
83     //------------------------- EnqueuePredicate implementation
84
/**
85      * @see EnqueuePredicate#accept(Object, Sink)
86      */

87     public boolean accept(Object JavaDoc element, Sink sink)
88     {
89         if (m_targetRate == -1.0)
90         {
91             return true;
92         }
93
94         // First regenerate tokens
95
long currentTime = System.currentTimeMillis();
96         long delay = currentTime - m_lastTime;
97
98         if (delay >= MIN_REGENERATION_TIME)
99         {
100             double numTokens = ((double) delay * 1.0) / (m_regenTimeMs * 1.0);
101             m_tokenCount += numTokens;
102
103             if (m_tokenCount > m_depth)
104             {
105                 m_tokenCount = m_depth;
106             }
107
108             m_lastTime = currentTime;
109         }
110
111         if (m_tokenCount >= 1)
112         {
113             m_tokenCount--;
114             return true;
115         }
116         else
117         {
118             return false;
119         }
120     }
121
122     /**
123      * @see EnqueuePredicate#accept(Object, Sink)
124      */

125     public boolean accept(Object JavaDoc[] elements, Sink sink)
126     {
127         if (m_targetRate == -1.0)
128         {
129             return true;
130         }
131
132         // First regenerate tokens
133
long currentTime = System.currentTimeMillis();
134         long delay = currentTime - m_lastTime;
135
136         if (delay >= MIN_REGENERATION_TIME)
137         {
138             double numTokens = ((double) delay * 1.0) / (m_regenTimeMs * 1.0);
139             m_tokenCount += numTokens;
140
141             if (m_tokenCount > m_depth)
142             {
143                 m_tokenCount = m_depth;
144             }
145             m_lastTime = currentTime;
146         }
147
148         if (m_tokenCount >= elements.length)
149         {
150             m_tokenCount -= elements.length;
151             return true;
152         }
153         else
154         {
155             return false;
156         }
157     }
158
159     //------------------------- RateLimitingPredicate specific implementation
160
/**
161      * Returns the current rate limit.
162      * @since May 15, 2002
163      *
164      * @return double
165      * the current target rate
166      */

167     public double getTargetRate()
168     {
169         return m_targetRate;
170     }
171
172     /**
173      * Returns the current depth.
174      * @since May 15, 2002
175      *
176      * @return int
177      * The current bucket depth.
178      */

179     public int getDepth()
180     {
181         return m_depth;
182     }
183
184     /**
185      * Returns the number of tokens currently in the bucket.
186      * @since May 15, 2002
187      *
188      * @return int
189      * the number of tokens currently in the bucket.
190      */

191     public int getBucketSize()
192     {
193         return (int) m_tokenCount;
194     }
195
196     /**
197      * Allows to set the rate limit. A limit of <m_code>-1.0</m_code>
198      * indicates no rate limit.
199      * @since May 15, 2002
200      *
201      * @param targetRate
202      * the current rate limit.
203      */

204     public void setTargetRate(double targetRate)
205     {
206         m_targetRate = targetRate;
207
208         m_regenTimeMs = (1.0 / targetRate) * 1.0e3;
209         if (m_regenTimeMs < 1)
210         {
211             m_regenTimeMs = 1;
212         }
213     }
214
215     /**
216      * Allows to set the bucket depth.
217      * @since May 15, 2002
218      *
219      * @param depth
220      * The bucket depth as an integer.
221      */

222     public void setDepth(int depth)
223     {
224         m_depth = depth;
225     }
226
227 }
228
Popular Tags