private void release(final ByteBuffer buffer) {
        if (buffer != null && buffer.isDirect()) {
            LOGGER.trace(() -> LogUtil.message("Releasing buffer with capacity: {}",
                    ModelStringUtil.formatCsv(buffer.capacity())));
            final int offset = getOffset(buffer.capacity());
            if (isUnPooled(offset)) {
                // Not pooled so need to release the memory via the cleaner
                unmapBuffer(buffer);
            } else {
                // Use offer rather than put as that will fail if the thread is interrupted but
                // we want the buffer back on the queue whatever happens, else the pool will be
                // exhausted.
                // As pooledBufferCounters controls the number of queued items we don't need to worry
                // about offer failing.
                final boolean didOfferSucceed = pooledBufferQueues[offset].offer(buffer);

                if (!didOfferSucceed) {
                    // We must have created more buffers than there are under pool control so we just have
                    // to unmap it
                    LOGGER.debug(() -> LogUtil.message("Unable to return buffer to the queue so will destroy it " +
                                    "(capacity: {}, queue size: {}, counter value: {}, configured limit: {}",
                            ModelStringUtil.formatCsv(buffer.capacity()),
                            pooledBufferQueues[offset].size(),
                            pooledBufferCounters[offset].get(),
                            maxBufferCounts[offset]));
                    unmapBuffer(buffer);
                }
            }
        } else {
            LOGGER.debug("buffer is null");
        }
    }
@param n The number to test
@return True if n is a power of ten, e.g. if n==10
stroom-bytebuffer/src/main/java/stroom/bytebuffer/ByteBufferPoolImpl4.java