217 return ByteBuffer.allocateDirect(size); 218 } 219 220 BufferCache cache = bufferCache.get(); 221 ByteBuffer buf = cache.get(size); 222 if (buf != null) { 223 return buf; 224 } else { 225 // No suitable buffer in the cache so we need to allocate a new 226 // one. To avoid the cache growing then we remove the first 227 // buffer from the cache and free it. 228 if (!cache.isEmpty()) { 229 buf = cache.removeFirst(); 230 free(buf); 231 } 232 return ByteBuffer.allocateDirect(size); 233 } 234 } 235 236 /** 237 * Releases a temporary buffer by returning to the cache or freeing it. 238 */ 239 public static void releaseTemporaryDirectBuffer(ByteBuffer buf) { 240 offerFirstTemporaryDirectBuffer(buf); 241 } 242 243 /** 244 * Releases a temporary buffer by returning to the cache or freeing it. If 245 * returning to the cache then insert it at the start so that it is 246 * likely to be returned by a subsequent call to getTemporaryDirectBuffer. 247 */ 248 static void offerFirstTemporaryDirectBuffer(ByteBuffer buf) { 249 // If the buffer is too large for the cache we don't have to 250 // check the cache. We'll just free it. 251 if (isBufferTooLarge(buf)) { 252 free(buf); 253 return; 254 } 255 256 assert buf != null; | 217 return ByteBuffer.allocateDirect(size); 218 } 219 220 BufferCache cache = bufferCache.get(); 221 ByteBuffer buf = cache.get(size); 222 if (buf != null) { 223 return buf; 224 } else { 225 // No suitable buffer in the cache so we need to allocate a new 226 // one. To avoid the cache growing then we remove the first 227 // buffer from the cache and free it. 228 if (!cache.isEmpty()) { 229 buf = cache.removeFirst(); 230 free(buf); 231 } 232 return ByteBuffer.allocateDirect(size); 233 } 234 } 235 236 /** 237 * Returns a temporary buffer of at least the given size and 238 * aligned to the alignment 239 */ 240 public static ByteBuffer getTemporaryAlignedDirectBuffer(int size, int alignment) { 241 if (isBufferTooLarge(size)) { 242 return ByteBuffer.allocateDirect(size + alignment - 1).alignedSlice(alignment); 243 } 244 245 BufferCache cache = bufferCache.get(); 246 ByteBuffer buf = cache.get(size); 247 if (buf != null) { 248 if (buf instanceof DirectBuffer) { 249 if (buf.alignmentOffset(0, alignment) == 0) { 250 return buf; 251 } 252 } 253 } else { 254 if (!cache.isEmpty()) { 255 buf = cache.removeFirst(); 256 free(buf); 257 } 258 } 259 return ByteBuffer.allocateDirect(size + alignment - 1).alignedSlice(alignment); 260 } 261 262 /** 263 * Releases a temporary buffer by returning to the cache or freeing it. 264 */ 265 public static void releaseTemporaryDirectBuffer(ByteBuffer buf) { 266 offerFirstTemporaryDirectBuffer(buf); 267 } 268 269 /** 270 * Releases a temporary buffer by returning to the cache or freeing it. If 271 * returning to the cache then insert it at the start so that it is 272 * likely to be returned by a subsequent call to getTemporaryDirectBuffer. 273 */ 274 static void offerFirstTemporaryDirectBuffer(ByteBuffer buf) { 275 // If the buffer is too large for the cache we don't have to 276 // check the cache. We'll just free it. 277 if (isBufferTooLarge(buf)) { 278 free(buf); 279 return; 280 } 281 282 assert buf != null; |