/** Returns a temporary buffer of at least the given size */ public static ByteBuffer getTemporaryDirectBuffer(int size) { // If a buffer of this size is too large for the cache, there // should not be a buffer in the cache that is at least as // large. So we'll just create a new one. Also, we don't have // to remove the buffer from the cache (as this method does // below) given that we won't put the new buffer in the cache. if (isBufferTooLarge(size)) { return ByteBuffer.allocateDirect(size); } BufferCache cache = bufferCache.get(); ByteBuffer buf = cache.get(size); if (buf != null) { return buf; } else { // No suitable buffer in the cache so we need to allocate a new // one. To avoid the cache growing then we remove the first // buffer from the cache and free it. if (!cache.isEmpty()) { buf = cache.removeFirst(); free(buf); } return ByteBuffer.allocateDirect(size); } }
/** * Releases a temporary buffer by returning to the cache or freeing it. If returning to the cache * then insert it at the end. This makes it suitable for scatter/gather operations where the * buffers are returned to cache in same order that they were obtained. */ static void offerLastTemporaryDirectBuffer(ByteBuffer buf) { // If the buffer is too large for the cache we don't have to // check the cache. We'll just free it. if (isBufferTooLarge(buf)) { free(buf); return; } assert buf != null; BufferCache cache = bufferCache.get(); if (!cache.offerLast(buf)) { // cache is full free(buf); } }