/** 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 if (m_pool != null) { next = m_pool.acquire(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); } }
@Override protected void flattenToBuffer(final DBBPool pool) throws IOException { int msgsize = 4 + 4 + 8 + 1 + 1 + 1 + 2; assert (m_exception == null || m_status != SUCCESS); if (m_exception != null) { msgsize += m_exception.getSerializedSize(); } else { msgsize += 4; // Still serialize exception length 0 } // stupid lame flattening of the tables ByteBuffer tableBytes = null; if (m_dependencyCount > 0) { FastSerializer fs = new FastSerializer(); try { for (int i = 0; i < m_dependencyCount; i++) fs.writeObject(m_dependencies.get(i)); } catch (IOException e) { e.printStackTrace(); assert (false); } tableBytes = fs.getBuffer(); msgsize += tableBytes.remaining(); msgsize += 4 * m_dependencyCount; } if (m_buffer == null) { m_container = pool.acquire(msgsize + 1 + HEADER_SIZE); m_buffer = m_container.b; } setBufferSize(msgsize + 1, pool); m_buffer.position(HEADER_SIZE); m_buffer.put(FRAGMENT_RESPONSE_ID); m_buffer.putInt(m_executorSiteId); m_buffer.putInt(m_destinationSiteId); m_buffer.putLong(m_txnId); m_buffer.put(m_status); m_buffer.put((byte) (m_dirty ? 1 : 0)); m_buffer.put((byte) (m_recovering ? 1 : 0)); m_buffer.putShort(m_dependencyCount); for (int i = 0; i < m_dependencyCount; i++) m_buffer.putInt(m_dependencyIds.get(i)); if (tableBytes != null) m_buffer.put(tableBytes); if (m_exception != null) { m_exception.serializeToBuffer(m_buffer); } else { m_buffer.putInt(0); } m_buffer.limit(m_buffer.position()); }
/** constructor that sets callback object. */ public FastSerializer( boolean bigEndian, boolean isDirect, BufferGrowCallback callback, DBBPool pool, int initialAllocation) { assert (initialAllocation > 0); assert (pool == null && isDirect || pool != null && !isDirect || pool == null && !isDirect); this.isDirect = isDirect; if (pool != null) { m_pool = pool; buffer = pool.acquire(initialAllocation); } else if (isDirect) { assert (pool == null); m_pool = null; buffer = DBBPool.allocateDirect(initialAllocation); } else { buffer = DBBPool.wrapBB(ByteBuffer.allocate(initialAllocation)); m_pool = null; assert (pool == null); } this.callback = callback; buffer.b.order(bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); }
/** * Read at most maxBytes from the network. Will read until the network would block, the stream is * closed or the maximum bytes to read is reached. * * @param maxBytes * @return -1 if closed otherwise total buffered bytes. In all cases, data may be buffered in the * stream - even when the channel is closed. */ final int read(ReadableByteChannel channel, int maxBytes, final DBBPool pool) throws IOException { int bytesRead = 0; int lastRead = 1; try { while (bytesRead < maxBytes && lastRead > 0) { if (m_writeBuffer == null) { m_writeBuffer = pool.acquire(BUFFER_SIZE); } lastRead = channel.read(m_writeBuffer.b); // EOF, no data read if (lastRead < 0 && bytesRead == 0) { if (m_writeBuffer.b.position() == 0) { m_writeBuffer.discard(); m_writeBuffer = null; } return -1; } // Data read if (lastRead > 0) { bytesRead += lastRead; if (!m_writeBuffer.b.hasRemaining()) { m_writeBuffer.b.flip(); m_readBuffers.add(m_writeBuffer); m_writeBuffer = null; } else { break; } } } } finally { if (bytesRead > 0) { m_globalAvailable.addAndGet(bytesRead); m_bytesRead.addAndGet(bytesRead); m_totalAvailable += bytesRead; } } return bytesRead; }