private ByteBuffer getBuffer(final int minCapacity) {
        // This method is called a LOT so needs to be performant

        ByteBuffer buffer = null;
        int count = 0;
        boolean isNewBuffer = false;
        final Key key = new Key(minCapacity, 0);
        while (buffer == null) {
            count++;
            // Get a buffer at least as big as minCapacity with the smallest insertionTime.
            // We don't really care about the insertTime, it is just there to give us a unique
            // key.  As the map is sorted on capacity then insertTime we will get the lowest insertTime
            // for a given capacity
            final Map.Entry<Key, ByteBuffer> entry = bufferMap.ceilingEntry(key);

            if (entry == null) {
                // No suitable buffer in the pool so make a new one
                buffer = createNewBuffer(minCapacity);
                isNewBuffer = true;
            } else {
                // Now try and remove the entry we found, though another thread may have stolen it
                final ByteBuffer poolBuffer = bufferMap.remove(entry.getKey());
                if (poolBuffer == null) {
                    // Another thread has beaten us to it and taken the entry, so go round again
                    if (minCapacity > largestBufferInPool.get() || totalPooledCapacity.get() < MAX_BYTES_IN_POOL) {
                        // Not may buffers in pool so just create a new one for them
                        buffer = createNewBuffer(minCapacity);
                        isNewBuffer = true;
                    }
                } else {
                    buffer = poolBuffer;
                }
            }
        }
//        if (LOGGER.isDebugEnabled()) {
//            if (count > 1) {
//                LOGGER.debug("Obtained {} buffer after {} iterations", (isNewBuffer ? "new" : "pooled"), count);
//            }
//            getCount.incrementAndGet();
//            requestsMap.computeIfAbsent(minCapacity, k -> new AtomicInteger(0))
//                    .incrementAndGet();
//        }
        return buffer;
    }
An unbounded self-populating pool of directly allocated ByteBuffers.
When using one of the methods to get/use a buffer from the pool the
smallest available buffer that is greater than or equal to the required
capacity will be provided. All buffers will be cleared on return to
the pool.
<p>
As this pool is un-bounded it could grow very large under high contention.
<p>
This impl uses a {@link ConcurrentSkipListMap} keyed on capacity and insert time
with no synchronisation.
stroom-bytebuffer/src/main/java/stroom/bytebuffer/ByteBufferPoolImpl.java