1 /**********************************************************************
2 * ByteBufferAllocator.java
3 * created on 12.03.2005 by netseeker
4 * $Source$
5 * $Date$
6 * $Revision$
7 *
8 * ====================================================================
9 *
10 * Copyright 2005-2006 netseeker aka Michael Manske
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 * ====================================================================
24 *
25 * This file is part of the ejoe framework.
26 * For more information on the author, please see
27 * <http://www.manskes.de/>.
28 *
29 *********************************************************************/
30 package de.netseeker.ejoe.cache;
31
32 import java.nio.ByteBuffer;
33
34 /***
35 * Utility supporting safe allocations and caching of ByteBuffers.
36 *
37 * @author netseeker
38 * @since 0.4.0
39 */
40 public class ByteBufferAllocator
41 {
42 private static ByteBufferCache _cache = new ByteBufferCache();
43
44 /***
45 * Allocates either a direct or a indirect ByteBuffer. If a indirect ByteBuffer was requested but could not be
46 * allocated because lack of free java heap, a direct ByteBuffer will be allocated and returned
47 *
48 * @param size target size of the requested new ByteBuffer
49 * @param direct
50 * @return either a direct or an indirect ByteBuffer depending on request and memory state
51 */
52 public static ByteBuffer allocate( int size, boolean direct )
53 {
54 ByteBuffer buffer = null;
55 if ( direct )
56 {
57 buffer = _cache.borrow( size );
58 }
59 else
60 {
61 try
62 {
63 buffer = ByteBuffer.allocate( size );
64 }
65 catch ( OutOfMemoryError e )
66 {
67 buffer = allocate( size, true );
68 }
69 }
70
71 return buffer;
72 }
73
74 /***
75 * Allocates either a direct or a indirect ByteBuffer. This method decides automatically if a direct or indirect
76 * ByteBuffer should be allocated.
77 *
78 * @param size target size of the requested new ByteBuffer
79 * @return either a direct or an indirect ByteBuffer depending on target size and memory state
80 * @param size
81 * @return
82 */
83 public static ByteBuffer allocate( int size )
84 {
85 return allocate( size, size >= 512 );
86 }
87
88 /***
89 * Resizes a given ByteBuffer to a new size.
90 *
91 * @param src ByteBuffer to get resized
92 * @param newSize size in bytes for the resized buffer
93 */
94 public static ByteBuffer reAllocate( ByteBuffer src, int newSize )
95 {
96 int pos = src.position();
97 if ( pos > 0 )
98 {
99 src.flip();
100 }
101 ByteBuffer bb = allocate( newSize, src.isDirect() );
102 bb.put( src );
103 bb.position( pos );
104 return bb;
105 }
106
107 /***
108 * Tries to clear and destroy a existing ByteBuffer
109 *
110 * @param buffer
111 */
112 public static void collect( ByteBuffer buffer )
113 {
114 if ( buffer != null && buffer.isDirect() )
115 {
116 _cache.pushBack( buffer );
117 }
118 }
119 }