/** Resizes the internal byte buffer with a simple doubling policy, if needed. */ private final void growIfNeeded(int minimumDesired) { if (buffer.b().remaining() < minimumDesired) { // Compute the size of the new buffer int newCapacity = buffer.b().capacity(); int newRemaining = newCapacity - buffer.b().position(); while (newRemaining < minimumDesired) { newRemaining += newCapacity; newCapacity *= 2; } // Allocate and copy BBContainer next; if (isDirect) { next = DBBPool.allocateDirect(newCapacity); } else { next = DBBPool.wrapBB(ByteBuffer.allocate(newCapacity)); } buffer.b().flip(); next.b().put(buffer.b()); assert next.b().remaining() == newRemaining; buffer.discard(); buffer = next; if (callback != null) callback.onBufferGrow(this); assert (buffer.b().order() == ByteOrder.BIG_ENDIAN); } }
BBContainer acquire() { final BBContainer cont = m_buffers.poll(); if (cont == null) { final BBContainer originContainer = DBBPool.allocateDirect(1024 * 32); return new BBContainer(originContainer.b()) { @Override public void discard() { checkDoubleFree(); // If we had to allocate over the desired limit, start discarding if (m_buffers.size() > m_numBuffers) { originContainer.discard(); return; } m_buffers.push(originContainer); } }; } return new BBContainer(cont.b()) { @Override public void discard() { checkDoubleFree(); m_buffers.push(cont); } }; }
/** constructor that sets callback object. */ public FastSerializer( boolean bigEndian, boolean isDirect, BufferGrowCallback callback, int initialAllocation) { assert (initialAllocation > 0); this.isDirect = isDirect; if (isDirect) { buffer = DBBPool.allocateDirect(initialAllocation); } else { buffer = DBBPool.wrapBB(ByteBuffer.allocate(initialAllocation)); } this.callback = callback; buffer.b().order(bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); }
private Container getOutputBuffer(final int nextChunkPartitionId) { Container c = m_buffers.poll(); if (c == null) { final BBContainer originContainer = DBBPool.allocateDirect(DEFAULT_CHUNKSIZE); final ByteBuffer b = originContainer.b; final long pointer = org.voltcore.utils.DBBPool.getBufferAddress(b); c = new Container(b, pointer, originContainer, nextChunkPartitionId); } /* * Need to reconstruct the container with the partition id of the next * chunk so it can be a final public field. The buffer, address, and origin * container remain the same. */ c = new Container(c.b, c.address, c.m_origin, nextChunkPartitionId); return c; }