Interface RegisteredBuffer

All Superinterfaces:
AutoCloseable

public interface RegisteredBuffer extends AutoCloseable
A pre-registered off-heap buffer for zero-copy I/O operations.

Registered buffers are memory regions that have been pre-validated and pinned by the kernel, eliminating per-operation address validation overhead. On Linux io_uring, this provides approximately 1.7x throughput improvement.

Buffer Lifecycle

  1. Acquire: Obtain a buffer from RegisteredBufferPool.acquire()
  2. Use: Read/write data using segment()
  3. Release: Return to pool via close() (auto-released)

Position and Limit

Similar to ByteBuffer, this buffer tracks position and limit:

  • Position: Current read/write offset in the buffer
  • Limit: Upper bound for read/write operations
  • Capacity: Total buffer size (immutable)
  • Remaining: limit - position (bytes available)

Usage Example

try (RegisteredBuffer buffer = pool.acquire()) {
    // Write data
    MemorySegment seg = buffer.segment();
    seg.setAtIndex(ValueLayout.JAVA_BYTE, 0, (byte) 'H');
    buffer.position(5);
    buffer.flip(); // Prepare for reading/sending

    // Send
    backend.send(buffer, token);
} // Auto-released back to pool

Thread Safety

Individual buffer instances are not thread-safe. Do not share a buffer across threads while it is in use. The pool itself is thread-safe for acquire/release operations.

See Also:
  • Method Summary

    Modifier and Type
    Method
    Description
    Returns the arena managing this buffer's memory lifecycle.
    long
    Returns the total capacity of this buffer in bytes.
    Clears the buffer for writing.
    void
    Releases this buffer back to its pool.
    Flips the buffer from writing to reading mode.
    long
    Gets the user-defined token previously set via setToken(long).
    boolean
    Checks if there are bytes remaining between position and limit.
    int
    Returns the registration index of this buffer.
    boolean
    Checks if this buffer is currently acquired from the pool.
    long
    Returns the current limit of the buffer.
    void
    limit(long limit)
    Sets the limit of the buffer.
    long
    Returns the current position in the buffer.
    void
    position(long position)
    Sets the current position in the buffer.
    long
    Returns the number of bytes between position and limit.
    Returns the underlying memory segment for direct data access.
    void
    setToken(long token)
    Sets a user-defined token for tracking this buffer through I/O operations.
  • Method Details

    • segment

      MemorySegment segment()
      Returns the underlying memory segment for direct data access.

      The segment provides zero-copy access to the buffer's off-heap memory. Use MemorySegment.get(ValueLayout.OfByte, long) and MemorySegment.set(ValueLayout.OfByte, long, byte) methods for type-safe memory access.

      Returns:
      the memory segment backing this buffer
    • index

      int index()
      Returns the registration index of this buffer.

      For io_uring backends, this is the buffer index used with IORING_OP_READ_FIXED and IORING_OP_WRITE_FIXED operations.

      Returns:
      the buffer's index in the registered buffer array (0-based)
    • capacity

      long capacity()
      Returns the total capacity of this buffer in bytes.

      This is the maximum amount of data the buffer can hold, set at pool creation time and immutable.

      Returns:
      the buffer capacity in bytes
    • position

      long position()
      Returns the current position in the buffer.

      Position marks the next byte to be read or written.

      Returns:
      the current position (0 to limit)
    • position

      void position(long position)
      Sets the current position in the buffer.
      Parameters:
      position - the new position (must be 0 to limit)
      Throws:
      IllegalArgumentException - if position is negative or exceeds limit
    • limit

      long limit()
      Returns the current limit of the buffer.

      Limit marks the end of valid data for reading, or the maximum write position.

      Returns:
      the current limit (0 to capacity)
    • limit

      void limit(long limit)
      Sets the limit of the buffer.

      If position exceeds the new limit, position is set to the limit.

      Parameters:
      limit - the new limit (must be 0 to capacity)
      Throws:
      IllegalArgumentException - if limit is negative or exceeds capacity
    • clear

      Clears the buffer for writing.

      Sets position to 0 and limit to capacity. Does not actually clear the data; just resets the markers.

      Returns:
      this buffer for method chaining
    • flip

      Flips the buffer from writing to reading mode.

      Sets limit to current position, then sets position to 0. Call after writing data and before reading or sending.

      Returns:
      this buffer for method chaining
    • remaining

      long remaining()
      Returns the number of bytes between position and limit.
      Returns:
      limit - position
    • hasRemaining

      boolean hasRemaining()
      Checks if there are bytes remaining between position and limit.
      Returns:
      true if remaining() > 0
    • isInUse

      boolean isInUse()
      Checks if this buffer is currently acquired from the pool.
      Returns:
      true if the buffer is in use, false if available
    • setToken

      void setToken(long token)
      Sets a user-defined token for tracking this buffer through I/O operations.

      This allows passing context through the I/O pipeline without allocation. The token is preserved until overwritten or the buffer is released.

      Parameters:
      token - the user-defined tracking token
    • getToken

      long getToken()
      Gets the user-defined token previously set via setToken(long).
      Returns:
      the tracking token, or 0 if not set
    • arena

      Arena arena()
      Returns the arena managing this buffer's memory lifecycle.
      Returns:
      the memory arena
    • close

      void close()
      Releases this buffer back to its pool.

      After calling close, the buffer must not be used. The buffer's contents may be overwritten by subsequent acquire operations.

      This method is idempotent; calling it multiple times has no effect.

      Specified by:
      close in interface AutoCloseable