/** 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);
 }
Exemple #4
0
  /**
   * 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;
  }