KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > protomatter > pool > GrowingObjectPool


1 package com.protomatter.pool;
2
3 /**
4  * {{{ The Protomatter Software License, Version 1.0
5  * derived from The Apache Software License, Version 1.1
6  *
7  * Copyright (c) 1998-2002 Nate Sammons. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed for the
24  * Protomatter Software Project
25  * (http://protomatter.sourceforge.net/)."
26  * Alternately, this acknowledgment may appear in the software itself,
27  * if and wherever such third-party acknowledgments normally appear.
28  *
29  * 4. The names "Protomatter" and "Protomatter Software Project" must
30  * not be used to endorse or promote products derived from this
31  * software without prior written permission. For written
32  * permission, please contact support@protomatter.com.
33  *
34  * 5. Products derived from this software may not be called "Protomatter",
35  * nor may "Protomatter" appear in their name, without prior written
36  * permission of the Protomatter Software Project
37  * (support@protomatter.com).
38  *
39  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
40  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42  * DISCLAIMED. IN NO EVENT SHALL THE PROTOMATTER SOFTWARE PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE. }}}
51  */

52
53 import java.util.*;
54 import com.protomatter.syslog.Syslog;
55
56 /**
57  * An ObjectPool implementation that has an initial size and an
58  * optional max size. The pool will grow as needed by blocks
59  * until the max size is reached.
60  *
61  * @see ObjectPool
62  * @see SimpleObjectPool
63  */

64 public abstract class GrowingObjectPool
65 extends SimpleObjectPool
66 {
67   private int maxPoolSize = -1;
68   private int initialPoolSize = 0;
69   private int createWaitTime = 0;
70   private int growBlock = 1;
71   private List pool = new ArrayList();
72
73   /**
74    * Initialize the object pool. Checked out
75    * objects will be monitored.
76    */

77   public GrowingObjectPool()
78   {
79     super();
80   }
81
82   /**
83    * Initialize the object pool. Checked out
84    * objects will be monitored if <TT>monitorCheckedOutObjects</TT>
85    * is true.
86    */

87   public GrowingObjectPool(boolean monitorCheckedOutObjects)
88   {
89     super(monitorCheckedOutObjects);
90   }
91
92   /**
93    * Get the pool.
94    */

95   protected List getPool()
96   {
97     return this.pool;
98   }
99
100   /**
101    * Get the number of objects in the pool that are available.
102    */

103   public int getObjectPoolSize()
104   {
105     return this.pool.size();
106   }
107
108   /**
109    * Get the current size of the pool. Returns (objects available
110    * + objects in use)
111    */

112   public int getCurrentPoolSize()
113   {
114     int size = 0;
115     synchronized (sync)
116     {
117       size = getObjectPoolSize() + getObjectsInUse();
118     }
119     return size;
120   }
121
122   /**
123    * Gets the next object from the pool. If the pool is
124    * empty, it is grown by not more than <tt>poolGrowBlock</tt> elements
125    * up to <tt>maxPoolSize</tt> total.
126    *
127    * @exception Exception If there is a problem getting the next
128    * object from the pool -- could be caused by the
129    * createObjectPoolObject() method throwing an exception.
130    */

131   protected ObjectPoolObject getNextPoolObject()
132   throws Exception JavaDoc
133   {
134     synchronized (sync)
135     {
136       // pool's not empty -- just get one from there
137
if (pool.size() > 0)
138       {
139         return (ObjectPoolObject)pool.remove(0);
140       }
141       // grow the pool by "growBlock" elements.
142
else if (getCurrentPoolSize() < maxPoolSize)
143       {
144         int currentPoolSize = getCurrentPoolSize();
145         for (int i=1; i<growBlock && (maxPoolSize + growBlock) >= currentPoolSize; i++)
146         {
147           pool.add(createObjectPoolObject());
148           doCreateWait();
149         }
150         return createObjectPoolObject();
151       }
152       // special case -- if pool size == -1, grow forever.
153
else if (maxPoolSize == -1)
154       {
155         for (int i=1; i<growBlock; i++)
156         {
157           pool.add(createObjectPoolObject());
158           doCreateWait();
159         }
160         return createObjectPoolObject();
161       }
162     }
163     // SOL -- better luck next time.
164
return null;
165   }
166
167   /**
168    * Change the maximum size of the object pool. The pool will be
169    * shrunk unless the number of objects in use (checked out of
170    * the pool) is larger than the new desired size of the pool or
171    * the desired size is smaller than the initial size of this pool.
172    *
173    * @throws PoolException If the number of objects in use is
174    * greater than the desired size of the pool, or if the
175    * desired size is smaller than the initial size for
176    * this pool.
177    */

178   public void setMaxObjectPoolSize(int size)
179   throws PoolException
180   {
181     synchronized (sync)
182     {
183       if (size < getObjectsInUse())
184       {
185         throw new PoolException(PoolResources.getResourceString(MessageConstants.CANNOT_SHRINK_POOL_1));
186       }
187       if (size < initialPoolSize)
188       {
189         throw new PoolException(PoolResources.getResourceString(MessageConstants.CANNOT_SHRINK_POOL_2));
190       }
191
192       // how many objects get evicted?
193
int evict = getCurrentPoolSize() - size;
194       if (evict > 0) // need to evict anybody?
195
{
196         for (int i=0; i<evict; i++)
197         {
198           ObjectPoolObject o = (ObjectPoolObject)pool.remove(0);
199           o.deleteObjectPoolObject(); // should handle cleanup
200
}
201       }
202       maxPoolSize = size;
203     }
204   }
205
206   private void doCreateWait()
207   {
208     if (createWaitTime > 0)
209     {
210       try
211       {
212         Thread.sleep(createWaitTime);
213       }
214       catch (InterruptedException JavaDoc x)
215       {
216         ;
217       }
218     }
219   }
220
221   /**
222    * Initialize the pool.
223    * Reads the following from the Map:<P>
224    * <dl>
225    *
226    * <dt><tt>pool.initialSize</tt> (Integer)</dt>
227    * <dd>The initial pool size (default is 0).</dd>
228    *
229    * <dt><tt>pool.maxSize</tt> (Integer)</dt>
230    * <dd>The max pool size (default is -1). If the max
231    * pool size is -1, the pool grows infinitely.</dd>
232    *
233    * <dt><tt>pool.growBlock</tt> (Integer)</dt>
234    * <dd>The grow size (default is 1). When a new
235    * object is needed, this many are created.</dd>
236    *
237    * <dt><tt>pool.createWaitTime</tt> (Integer)</dt>
238    * <dd>The time (in ms) to sleep between pool object creates
239    * (default is 0). This is useful for database connection
240    * pools where it's possible to overload the database by
241    * trying to make too many connections too quickly.</dd>
242    *
243    * </dl><P>
244    *
245    * @exception Exception If there is an exception initializing the pool.
246    */

247   public void init(Map ht)
248   throws Exception JavaDoc
249   {
250     Integer JavaDoc ips = (Integer JavaDoc)ht.get("pool.initialSize");
251     if (ips != null)
252       initialPoolSize = ips.intValue();
253
254     Integer JavaDoc mps = (Integer JavaDoc)ht.get("pool.maxSize");
255     if (mps != null)
256       maxPoolSize = mps.intValue();
257
258     Integer JavaDoc pgb = (Integer JavaDoc)ht.get("pool.growBlock");
259     if (pgb != null)
260       growBlock = pgb.intValue();
261
262     Integer JavaDoc cwt = (Integer JavaDoc)ht.get("pool.createWaitTime");
263     if (cwt != null)
264       createWaitTime = cwt.intValue();
265
266     // load up the pool.
267
for (int i=0; i<initialPoolSize; i++)
268     {
269       pool.add(createObjectPoolObject());
270     }
271   }
272
273   /**
274    * Calls <tt>deleteObjectPoolObject()</tt> on all objects
275    * currently in the pool, and then re-creates the initial
276    * number of them.
277    *
278    * @exception Exception If there is an exception re-initializing the pool.
279    */

280   public void reInitializeObjectPool()
281   throws Exception JavaDoc
282   {
283     synchronized (sync)
284     {
285       Iterator it = pool.iterator();
286       while (it.hasNext())
287       {
288         ObjectPoolObject obj = (ObjectPoolObject)it.next();
289         obj.deleteObjectPoolObject();
290       }
291       pool.clear();
292
293       for (int i=0; i<initialPoolSize; i++)
294       {
295         pool.add(createObjectPoolObject());
296         doCreateWait();
297       }
298     }
299   }
300
301   /**
302    * @see SimpleObjectPool
303    */

304   protected void checkinPoolObject(ObjectPoolObject o)
305   {
306     pool.add(o);
307   }
308
309   /**
310    * Get the initial size of the pool.
311    */

312   public int getInitialObjectPoolSize()
313   {
314     return this.initialPoolSize;
315   }
316
317   /**
318    * Get the maximum number of objects this pool will hold.
319    */

320   public int getMaxObjectPoolSize()
321   {
322     return this.maxPoolSize;
323   }
324
325   /**
326    * Get the number of objects the pool should grow by when
327    * it needs to grow.
328    */

329   public int getObjectPoolGrowSize()
330   {
331     return this.growBlock;
332   }
333
334   /**
335    * Get the number of milliseconds to sleep between
336    * creates of new objects for the pool.
337    */

338   public int getCreateWaitTime()
339   {
340     return this.createWaitTime;
341   }
342 }
343
Popular Tags