KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > portal > generic > BufferFactoryImpl


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

48
49
50 package com.caucho.portal.generic;
51
52 import java.io.IOException JavaDoc;
53 import java.io.OutputStream JavaDoc;
54 import java.io.Writer JavaDoc;
55 import java.util.ArrayList JavaDoc;
56 import java.util.logging.Level JavaDoc;
57 import java.util.logging.Logger JavaDoc;
58
59 public class BufferFactoryImpl implements BufferFactory
60 {
61   static protected final Logger JavaDoc log =
62     Logger.getLogger(BufferFactoryImpl.class.getName());
63
64   private static int _bufferCount = 10;
65
66   private int _bufferSize = 8192;
67   private int _poolSize = 32;
68
69   FreeList<CharBufferImpl> _charBufferFreeList
70     = new FreeList<CharBufferImpl>(_poolSize);
71
72   FreeList<ByteBufferImpl> _byteBufferFreeList
73     = new FreeList<ByteBufferImpl>(_poolSize);
74
75
76   public void setBufferSize(int bufferSize)
77   {
78     synchronized (_byteBufferFreeList) {
79       synchronized (_charBufferFreeList) {
80         _byteBufferFreeList.clear();
81         _charBufferFreeList.clear();
82         _bufferSize = bufferSize;
83       }
84     }
85   }
86
87   public void setPoolSize(int poolSize)
88   {
89     synchronized (_byteBufferFreeList) {
90       synchronized (_charBufferFreeList) {
91         _poolSize = poolSize;
92         _byteBufferFreeList.ensureCapacity(poolSize);
93         _charBufferFreeList.ensureCapacity(poolSize);
94       }
95     }
96   }
97
98   public int getDefaultBufferSize()
99   {
100     return _bufferSize;
101   }
102
103   public PortletCharBuffer allocateCharBuffer(int capacity)
104   {
105     CharBufferImpl b = null;
106
107     if (capacity == Integer.MAX_VALUE)
108       capacity = _bufferSize;
109     else if (capacity < _bufferSize)
110       capacity = _bufferSize;
111
112     if (capacity == _bufferSize)
113       b = _charBufferFreeList.allocate();
114
115     if (b == null) {
116       b = new CharBufferImpl(capacity);
117
118       if (log.isLoggable(Level.FINEST))
119         b.log("allocated new with capacity " + capacity);
120     }
121     else {
122       if (log.isLoggable(Level.FINEST))
123         b.log("allocated reused with capacity " + b.getCapacity());
124     }
125
126     return b;
127   }
128
129   public PortletByteBuffer allocateByteBuffer(int capacity)
130   {
131     ByteBufferImpl b = null;
132
133     if (capacity == Integer.MAX_VALUE)
134       capacity = _bufferSize;
135     else if (capacity <= _bufferSize)
136       capacity = _bufferSize;
137
138     b = _byteBufferFreeList.allocate();
139
140     if (b == null) {
141       b = new ByteBufferImpl(capacity);
142
143       if (log.isLoggable(Level.FINEST))
144         b.log("allocated new with capacity " + capacity);
145     }
146     else {
147       if (log.isLoggable(Level.FINEST))
148         b.log("allocated reused with capacity " + b.getCapacity());
149     }
150
151     return b;
152   }
153   
154   private class CharBufferImpl implements PortletCharBuffer
155   {
156     private String JavaDoc _bufferId;
157
158     private int _bufferSize;
159     private char[] _buf;
160     private int _bufferPos = 0;
161
162     public CharBufferImpl(int size)
163     {
164       int id = _bufferCount++;
165       _bufferId = Integer.toString(id, Character.MAX_RADIX);
166
167       _bufferSize = size;
168       _buf = new char[size];
169     }
170
171     void log(String JavaDoc message)
172     {
173       if (log.isLoggable(Level.FINEST)) {
174         message = new StringBuffer JavaDoc(256).append("char buffer ")
175                                        .append(_bufferId)
176                                        .append(' ')
177                                        .append(message)
178                                        .toString();
179
180         log.log(Level.FINEST, message);
181       }
182     }
183
184     public boolean print(char buf[], int off, int len)
185     {
186       if (len > _bufferSize - _bufferPos)
187         return overrun();
188       else {
189         System.arraycopy(buf, off, _buf, _bufferPos, len);
190         _bufferPos += len;
191
192         return true;
193       }
194     }
195
196     public boolean print(String JavaDoc str, int off, int len)
197     {
198       if (len > _bufferSize - _bufferPos)
199         return overrun();
200       else {
201         str.getChars(off, off + len, _buf, _bufferPos);
202         _bufferPos += len;
203
204         return true;
205       }
206     }
207
208     public boolean print(int c)
209     {
210       if (_bufferPos == _bufferSize)
211         return overrun();
212       else {
213         _buf[_bufferPos++] = (char) c;
214
215         return true;
216       }
217     }
218
219     private boolean overrun()
220     {
221       log("overrun");
222       return false;
223     }
224
225     public void flush(Writer JavaDoc out)
226       throws IOException JavaDoc
227     {
228       if (_bufferPos != 0) {
229         log("flush");
230
231         out.write(_buf, 0, _bufferPos);
232         _bufferPos = 0;
233       }
234     }
235
236     public int size()
237     {
238       return _bufferPos;
239     }
240
241     public int getCapacity()
242     {
243       return _bufferSize;
244     }
245
246     public void reset()
247     {
248       log("reset");
249
250       _bufferPos = 0;
251     }
252
253     public void finish()
254     {
255       _bufferPos = 0;
256
257       log("finish");
258
259       if (_bufferSize <= BufferFactoryImpl.this._bufferSize) {
260         if (!_charBufferFreeList.free(this))
261           _buf = null;
262       }
263       else
264         _buf = null;
265     }
266   }
267
268   private class ByteBufferImpl implements PortletByteBuffer
269   {
270     private String JavaDoc _bufferId;
271
272     private int _bufferSize;
273     private byte[] _buf;
274     private int _bufferPos = 0;
275
276     public ByteBufferImpl(int size)
277     {
278       int id = _bufferCount++;
279       _bufferId = Integer.toString(id, Character.MAX_RADIX);
280
281       _bufferSize = size;
282       _buf = new byte[size];
283     }
284
285     void log(String JavaDoc message)
286     {
287       if (log.isLoggable(Level.FINEST)) {
288         message = new StringBuffer JavaDoc(256).append("byte buffer ")
289                                        .append(_bufferId)
290                                        .append(' ')
291                                        .append(message)
292                                        .toString();
293
294         log.log(Level.FINEST, message);
295       }
296     }
297
298     public boolean write(byte[] buf, int off, int len)
299     {
300       if (len > _bufferSize - _bufferPos)
301         return overrun();
302       else {
303         System.arraycopy(buf, off, _buf, _bufferPos, len);
304         _bufferPos += len;
305
306         return true;
307       }
308     }
309
310     /**
311      * @return false if the buffer is full and the byte could not be written
312      */

313     public boolean write(int b)
314     {
315       if (_bufferPos == _bufferSize)
316         return overrun();
317       else {
318         _buf[_bufferPos++] = (byte) b;
319
320         return true;
321       }
322     }
323
324     public int size()
325     {
326       return _bufferPos;
327     }
328
329     public int getCapacity()
330     {
331       return _bufferSize;
332     }
333
334     private boolean overrun()
335     {
336       log("overrun");
337       return false;
338     }
339
340     public void flush(OutputStream JavaDoc out)
341       throws IOException JavaDoc
342     {
343       if (_bufferPos != 0) {
344         log("flush");
345         out.write(_buf, 0, _bufferPos);
346         _bufferPos = 0;
347       }
348     }
349
350     public void reset()
351     {
352       log("reset");
353       _bufferPos = 0;
354     }
355
356     public void finish()
357     {
358       _bufferPos = 0;
359       log("finish");
360
361       if (_bufferSize <= BufferFactoryImpl.this._bufferSize) {
362         if (!_byteBufferFreeList.free(this))
363           _buf = null;
364       }
365       else
366         _buf = null;
367     }
368   }
369
370   private class FreeList<E>
371   {
372     private int _freeListSize;
373     private ArrayList JavaDoc<E> _freeList;
374
375     private long _lastAllocateFail;
376
377     public FreeList(int initialCapacity)
378     {
379       _freeListSize = initialCapacity;
380       _freeList = new ArrayList JavaDoc<E>(_freeListSize);
381     }
382
383     public E allocate()
384     {
385       synchronized (_freeList) {
386         int size = _freeList.size();
387
388         if (size > 0)
389           return _freeList.remove(--size);
390       }
391
392
393       return null;
394     }
395
396     public boolean free(E obj)
397     {
398       synchronized (_freeList) {
399         int size = _freeList.size();
400
401         if (size < _freeListSize) {
402           _freeList.add(obj);
403           return true;
404         }
405         else {
406           if (log.isLoggable(Level.CONFIG))
407             log.config("buffer pool overrun, consider increasing buffer-factory pool-size");
408           return false;
409         }
410       }
411     }
412
413     public void clear()
414     {
415       synchronized (_freeList) {
416         _freeList.clear();
417       }
418     }
419
420     public void ensureCapacity(int capacity)
421     {
422       synchronized (_freeList) {
423         _freeList.ensureCapacity(capacity);
424       }
425     }
426   }
427 }
428
Popular Tags