GlueGen v2.6.0-rc-20250712
GlueGen, Native Binding Generator for Java™ (public API).
CachedBufferFactory.java
Go to the documentation of this file.
1
2/*
3 * Copyright 2011 JogAmp Community. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification, are
6 * permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * The views and conclusions contained in the software and documentation are those of the
26 * authors and should not be interpreted as representing official policies, either expressed
27 * or implied, of JogAmp Community.
28 */
29
30/*
31 * Created on Sunday, February 13 2011 15:17
32 */
33package com.jogamp.common.nio;
34
35import java.nio.ByteBuffer;
36import java.nio.CharBuffer;
37import java.nio.DoubleBuffer;
38import java.nio.FloatBuffer;
39import java.nio.IntBuffer;
40import java.nio.LongBuffer;
41import java.nio.ShortBuffer;
42
43/**
44 * Buffer factory attempting to reduce buffer creation overhead.
45 * Direct ByteBuffers must be page aligned which increases creation overhead of
46 * small buffers significantly.
47 * This factory can be used as fixed size static or or dynamic allocating
48 * factory. The initial size and allocation size is configurable.
49 * <p>
50 * Fixed size factories may be used in systems with hard realtime requirements
51 * and/or predictable memory usage.
52 * </p>
53 * <p>
54 * concurrency info:<br/>
55 * <ul>
56 * <li>all create methods are threadsafe</li>
57 * <li>factories created with create(...) are <b>not</b> threadsafe</li>
58 * <li>factories created with createSynchronized(...) are threadsafe</li>
59 * </ul>
60 * </p>
61 *
62 * @author Michael Bien
63 */
64public class CachedBufferFactory {
65
66 /**
67 * default size for internal buffer allocation.
68 */
69 public static final int DEFAULT_ALLOCATION_SIZE = 1024 * 1024;
70
71 private final int ALLOCATION_SIZE;
72 private ByteBuffer currentBuffer;
73
74 private CachedBufferFactory() {
76 }
77
78 private CachedBufferFactory(final int initialSize, final int allocationSize) {
79 currentBuffer = Buffers.newDirectByteBuffer(initialSize);
80 ALLOCATION_SIZE = allocationSize;
81 }
82
83
84 /**
85 * Creates a factory with initial size and allocation size set to
86 * {@link #DEFAULT_ALLOCATION_SIZE}.
87 */
88 public static CachedBufferFactory create() {
89 return new CachedBufferFactory();
90 }
91
92 /**
93 * Creates a factory with the specified initial size. The allocation size is set to
94 * {@link #DEFAULT_ALLOCATION_SIZE}.
95 */
96 public static CachedBufferFactory create(final int initialSize) {
97 return new CachedBufferFactory(initialSize, DEFAULT_ALLOCATION_SIZE);
98 }
99
100 /**
101 * Creates a factory with the specified initial size. The allocation size is set to
102 * {@link #DEFAULT_ALLOCATION_SIZE}.
103 * @param fixed Creates a fixed size factory which will handle overflows (initial size)
104 * with RuntimeExceptions.
105 */
106 public static CachedBufferFactory create(final int initialSize, final boolean fixed) {
107 return new CachedBufferFactory(initialSize, fixed?-1:DEFAULT_ALLOCATION_SIZE);
108 }
109
110 /**
111 * Creates a factory with the specified initial size and allocation size.
112 */
113 public static CachedBufferFactory create(final int initialSize, final int allocationSize) {
114 return new CachedBufferFactory(initialSize, allocationSize);
115 }
116
117
118 /**
119 * Synchronized version of {@link #create()}.
120 */
122 return new SynchronizedCachedBufferFactory();
123 }
124
125 /**
126 * Synchronized version of {@link #create(int)}.
127 */
128 public static CachedBufferFactory createSynchronized(final int initialSize) {
129 return new SynchronizedCachedBufferFactory(initialSize, DEFAULT_ALLOCATION_SIZE);
130 }
131
132 /**
133 * Synchronized version of {@link #create(int, boolean)}.
134 */
135 public static CachedBufferFactory createSynchronized(final int initialSize, final boolean fixed) {
136 return new SynchronizedCachedBufferFactory(initialSize, fixed?-1:DEFAULT_ALLOCATION_SIZE);
137 }
138
139 /**
140 * Synchronized version of {@link #create(int, int)}.
141 */
142 public static CachedBufferFactory createSynchronized(final int initialSize, final int allocationSize) {
143 return new CachedBufferFactory(initialSize, allocationSize);
144 }
145
146 /**
147 * Returns true only if this factory does not allow to allocate more buffers
148 * as limited by the initial size.
149 */
150 public boolean isFixed() {
151 return ALLOCATION_SIZE == -1;
152 }
153
154 /**
155 * Returns the allocation size used to create new internal buffers.
156 * 0 means that the buffer will not grows, see {@link #isFixed()}.
157 */
158 public int getAllocationSize() {
159 return ALLOCATION_SIZE;
160 }
161
162 /**
163 * @return true if buffer cannot grow, otherwise false
164 */
165 private void checkIfFixed() {
166 if(ALLOCATION_SIZE == 0) {
167 throw new RuntimeException("fixed size buffer factory ran out ouf bounds.");
168 }
169 }
170
171 public void destroy() {
172 if(null != currentBuffer) {
173 currentBuffer.clear();
174 currentBuffer = null;
175 }
176 }
177 public ByteBuffer newDirectByteBuffer(final int size) {
178
179 // if large enough... just create it
180 if (size > currentBuffer.capacity()) {
181 checkIfFixed();
182 return Buffers.newDirectByteBuffer(size);
183 }
184
185 // create new internal buffer if the old is running full
186 if (size > currentBuffer.remaining()) {
187 checkIfFixed();
188 currentBuffer = Buffers.newDirectByteBuffer(ALLOCATION_SIZE);
189 }
190
191 currentBuffer.limit(currentBuffer.position() + size);
192 final ByteBuffer result = currentBuffer.slice().order(currentBuffer.order());
193 currentBuffer.position(currentBuffer.limit());
194 currentBuffer.limit(currentBuffer.capacity());
195 return result;
196 }
197
198
199 public ByteBuffer newDirectByteBuffer(final byte[] values, final int offset, final int lenght) {
200 return (ByteBuffer)newDirectByteBuffer(lenght).put(values, offset, lenght).rewind();
201 }
202
203 public ByteBuffer newDirectByteBuffer(final byte[] values, final int offset) {
204 return newDirectByteBuffer(values, offset, values.length-offset);
205 }
206
207 public ByteBuffer newDirectByteBuffer(final byte[] values) {
208 return newDirectByteBuffer(values, 0);
209 }
210
211 public DoubleBuffer newDirectDoubleBuffer(final int numElements) {
212 return newDirectByteBuffer(numElements * Buffers.SIZEOF_DOUBLE).asDoubleBuffer();
213 }
214
215 public DoubleBuffer newDirectDoubleBuffer(final double[] values, final int offset, final int lenght) {
216 return (DoubleBuffer)newDirectDoubleBuffer(lenght).put(values, offset, lenght).rewind();
217 }
218
219 public DoubleBuffer newDirectDoubleBuffer(final double[] values, final int offset) {
220 return newDirectDoubleBuffer(values, offset, values.length - offset);
221 }
222
223 public DoubleBuffer newDirectDoubleBuffer(final double[] values) {
224 return newDirectDoubleBuffer(values, 0);
225 }
226
227 public FloatBuffer newDirectFloatBuffer(final int numElements) {
228 return newDirectByteBuffer(numElements * Buffers.SIZEOF_FLOAT).asFloatBuffer();
229 }
230
231 public FloatBuffer newDirectFloatBuffer(final float[] values, final int offset, final int lenght) {
232 return (FloatBuffer)newDirectFloatBuffer(lenght).put(values, offset, lenght).rewind();
233 }
234
235 public FloatBuffer newDirectFloatBuffer(final float[] values, final int offset) {
236 return newDirectFloatBuffer(values, offset, values.length - offset);
237 }
238
239 public FloatBuffer newDirectFloatBuffer(final float[] values) {
240 return newDirectFloatBuffer(values, 0);
241 }
242
243 public IntBuffer newDirectIntBuffer(final int numElements) {
244 return newDirectByteBuffer(numElements * Buffers.SIZEOF_INT).asIntBuffer();
245 }
246
247 public IntBuffer newDirectIntBuffer(final int[] values, final int offset, final int lenght) {
248 return (IntBuffer)newDirectIntBuffer(lenght).put(values, offset, lenght).rewind();
249 }
250
251 public IntBuffer newDirectIntBuffer(final int[] values, final int offset) {
252 return newDirectIntBuffer(values, offset, values.length - offset);
253 }
254
255 public IntBuffer newDirectIntBuffer(final int[] values) {
256 return newDirectIntBuffer(values, 0);
257 }
258
259 public LongBuffer newDirectLongBuffer(final int numElements) {
260 return newDirectByteBuffer(numElements * Buffers.SIZEOF_LONG).asLongBuffer();
261 }
262
263 public LongBuffer newDirectLongBuffer(final long[] values, final int offset, final int lenght) {
264 return (LongBuffer)newDirectLongBuffer(lenght).put(values, offset, lenght).rewind();
265 }
266
267 public LongBuffer newDirectLongBuffer(final long[] values, final int offset) {
268 return newDirectLongBuffer(values, offset, values.length - offset);
269 }
270
271 public LongBuffer newDirectLongBuffer(final long[] values) {
272 return newDirectLongBuffer(values, 0);
273 }
274
275 public ShortBuffer newDirectShortBuffer(final int numElements) {
276 return newDirectByteBuffer(numElements * Buffers.SIZEOF_SHORT).asShortBuffer();
277 }
278
279 public ShortBuffer newDirectShortBuffer(final short[] values, final int offset, final int lenght) {
280 return (ShortBuffer)newDirectShortBuffer(lenght).put(values, offset, lenght).rewind();
281 }
282
283 public ShortBuffer newDirectShortBuffer(final short[] values, final int offset) {
284 return newDirectShortBuffer(values, offset, values.length - offset);
285 }
286
287 public ShortBuffer newDirectShortBuffer(final short[] values) {
288 return newDirectShortBuffer(values, 0);
289 }
290
291 public CharBuffer newDirectCharBuffer(final int numElements) {
292 return newDirectByteBuffer(numElements * Buffers.SIZEOF_SHORT).asCharBuffer();
293 }
294
295 public CharBuffer newDirectCharBuffer(final char[] values, final int offset, final int lenght) {
296 return (CharBuffer)newDirectCharBuffer(lenght).put(values, offset, lenght).rewind();
297 }
298
299 public CharBuffer newDirectCharBuffer(final char[] values, final int offset) {
300 return newDirectCharBuffer(values, offset, values.length - offset);
301 }
302
303 public CharBuffer newDirectCharBuffer(final char[] values) {
304 return newDirectCharBuffer(values, 0);
305 }
306
307 @Override
308 public boolean equals(final Object obj) {
309 if (obj == null) {
310 return false;
311 }
312 if (getClass() != obj.getClass()) {
313 return false;
314 }
315 final CachedBufferFactory other = (CachedBufferFactory) obj;
316 if (this.ALLOCATION_SIZE != other.ALLOCATION_SIZE) {
317 return false;
318 }
319 if (this.currentBuffer != other.currentBuffer && (this.currentBuffer == null || !this.currentBuffer.equals(other.currentBuffer))) {
320 return false;
321 }
322 return true;
323 }
324
325 @Override
326 public String toString() {
327 return getClass().getName()+"[static:"+isFixed()+" alloc size:"+getAllocationSize()+"]";
328 }
329
330
331 // nothing special, just synchronized
332 private static class SynchronizedCachedBufferFactory extends CachedBufferFactory {
333
334 private SynchronizedCachedBufferFactory() {
335 super();
336 }
337
338 private SynchronizedCachedBufferFactory(final int size, final int step) {
339 super(size, step);
340 }
341
342 @Override
343 public synchronized ByteBuffer newDirectByteBuffer(final int size) {
344 return super.newDirectByteBuffer(size);
345 }
346
347 }
348
349}
Utility methods allowing easy java.nio.Buffer manipulations.
Definition: Buffers.java:70
static ByteBuffer newDirectByteBuffer(final int numElements)
Allocates a new direct ByteBuffer with the specified number of elements.
Definition: Buffers.java:92
static final int SIZEOF_SHORT
Definition: Buffers.java:78
static final int SIZEOF_DOUBLE
Definition: Buffers.java:83
static final int SIZEOF_INT
Definition: Buffers.java:80
static final int SIZEOF_LONG
Definition: Buffers.java:82
static final int SIZEOF_FLOAT
Definition: Buffers.java:81
Buffer factory attempting to reduce buffer creation overhead.
LongBuffer newDirectLongBuffer(final long[] values)
IntBuffer newDirectIntBuffer(final int numElements)
ShortBuffer newDirectShortBuffer(final short[] values, final int offset, final int lenght)
ByteBuffer newDirectByteBuffer(final byte[] values, final int offset, final int lenght)
static CachedBufferFactory create()
Creates a factory with initial size and allocation size set to DEFAULT_ALLOCATION_SIZE.
ShortBuffer newDirectShortBuffer(final short[] values)
static CachedBufferFactory createSynchronized(final int initialSize, final boolean fixed)
Synchronized version of create(int, boolean).
IntBuffer newDirectIntBuffer(final int[] values, final int offset, final int lenght)
CharBuffer newDirectCharBuffer(final char[] values)
ByteBuffer newDirectByteBuffer(final byte[] values, final int offset)
static CachedBufferFactory createSynchronized(final int initialSize, final int allocationSize)
Synchronized version of create(int, int).
int getAllocationSize()
Returns the allocation size used to create new internal buffers.
IntBuffer newDirectIntBuffer(final int[] values)
FloatBuffer newDirectFloatBuffer(final float[] values)
static CachedBufferFactory create(final int initialSize, final boolean fixed)
Creates a factory with the specified initial size.
static CachedBufferFactory createSynchronized()
Synchronized version of create().
static CachedBufferFactory create(final int initialSize, final int allocationSize)
Creates a factory with the specified initial size and allocation size.
boolean isFixed()
Returns true only if this factory does not allow to allocate more buffers as limited by the initial s...
CharBuffer newDirectCharBuffer(final char[] values, final int offset, final int lenght)
LongBuffer newDirectLongBuffer(final long[] values, final int offset, final int lenght)
DoubleBuffer newDirectDoubleBuffer(final double[] values, final int offset, final int lenght)
static final int DEFAULT_ALLOCATION_SIZE
default size for internal buffer allocation.
FloatBuffer newDirectFloatBuffer(final float[] values, final int offset, final int lenght)
static CachedBufferFactory createSynchronized(final int initialSize)
Synchronized version of create(int).
LongBuffer newDirectLongBuffer(final long[] values, final int offset)
ByteBuffer newDirectByteBuffer(final byte[] values)
LongBuffer newDirectLongBuffer(final int numElements)
static CachedBufferFactory create(final int initialSize)
Creates a factory with the specified initial size.
FloatBuffer newDirectFloatBuffer(final int numElements)
CharBuffer newDirectCharBuffer(final char[] values, final int offset)
CharBuffer newDirectCharBuffer(final int numElements)
ShortBuffer newDirectShortBuffer(final short[] values, final int offset)
FloatBuffer newDirectFloatBuffer(final float[] values, final int offset)
IntBuffer newDirectIntBuffer(final int[] values, final int offset)
DoubleBuffer newDirectDoubleBuffer(final double[] values)
DoubleBuffer newDirectDoubleBuffer(final int numElements)
DoubleBuffer newDirectDoubleBuffer(final double[] values, final int offset)
ShortBuffer newDirectShortBuffer(final int numElements)