Interface BufferRef
- All Known Implementing Classes:
BufferRefImpl
This is the fundamental "Atom" of the transport's buffer system. It wraps a MemorySegment with explicit ownership semantics via reference counting, designed for efficient
pooling and reuse.
Reference Counting
BufferRef uses explicit reference counting for memory management:
- Acquire: When obtained from pool, refCount starts at 1
- Retain: Call
retain()to increment count when sharing - Release: Call
release()when done; auto-returns to pool at 0
Usage Pattern
BufferRef buf = pool.acquire();
try {
// Write data to segment
buf.segment().setAtIndex(ValueLayout.JAVA_BYTE, 0, data);
buf.length(dataLen);
// If sharing with another thread:
buf.retain();
executor.submit(() -> {
try {
process(buf);
} finally {
buf.release();
}
});
} finally {
buf.release(); // Returns to pool when refCount hits 0
}
Structure of Arrays (SoA) Pattern
The poolIndex() method supports SoA patterns where metadata (timestamps, flags, etc.)
is stored in separate primitive arrays indexed by pool index, avoiding object header overhead.
Thread Safety
Reference counting operations (retain(), release()) are thread-safe using
lock-free CAS operations. The underlying segment access is not synchronized; callers must ensure
proper happens-before relationships.
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionlongaddress()Returns the raw native address of the segment.intlength()Returns the current length of valid data in the buffer.voidlength(int newLength) Sets the length of valid data in the buffer.intReturns the unique index of this buffer in the global pool.shortReturns the io_uring registration ID if registered.voidrelease()Decrements the reference count.voidretain()Increments the reference count.segment()Returns the underlying FFM MemorySegment.
-
Method Details
-
segment
MemorySegment segment()Returns the underlying FFM MemorySegment.Warning: Accessing this segment after
release()has reduced the refCount to 0 is undefined behavior. The segment may be reused by another thread or the underlying memory may be invalidated.- Returns:
- the memory segment backing this buffer
-
address
long address()Returns the raw native address of the segment.This is cached to avoid JNI/FFM overhead on hot paths. Useful for direct native library integration.
- Returns:
- the native memory address
-
poolIndex
int poolIndex()Returns the unique index of this buffer in the global pool.This enables "Structure of Arrays" (SoA) patterns where metadata (refCounts, timestamps, operation tokens) is stored in separate primitive arrays indexed by this ID, rather than in object fields.
- Returns:
- the buffer's index in its pool (0-based)
-
registrationId
short registrationId()Returns the io_uring registration ID if registered.For io_uring backends, this is the buffer index used with
IORING_OP_READ_FIXEDandIORING_OP_WRITE_FIXED.- Returns:
- the registration ID, or -1 if not registered
-
length
int length()Returns the current length of valid data in the buffer.This represents the actual payload size (e.g., packet length), not the buffer capacity.
- Returns:
- the valid data length in bytes
-
length
void length(int newLength) Sets the length of valid data in the buffer.- Parameters:
newLength- the new data length in bytes
-
retain
void retain()Increments the reference count.Must be called before sharing the buffer with another thread or holding it asynchronously past the current scope.
- Throws:
IllegalStateException- if refCount is already 0 (buffer released)
-
release
void release()Decrements the reference count.If the count reaches 0, the buffer is automatically returned to its pool for reuse. After the final release, the buffer must not be accessed.
- Throws:
IllegalStateException- if refCount is already 0 (double-release)
-