Views
Buffers support zero-copy views, allowing parts of an existing buffer to be accessed or modified without allocating new arrays.
Views are lightweight wrappers over the same underlying memory and are commonly used in high-throughput scenarios to avoid unnecessary allocations.
Two types of views exist:
- Readable views — windowed access to existing data
- Writable views — bounded patch windows over existing data
Readable Views
Readable buffers may represent a windowed view over a backing array.
This means:
- No data is copied when creating sub-buffers via
GetByteBufferorReadByteBuffer. - Multiple readable buffers may share the same underlying array.
Example:
This creates a readable buffer representing only the requested portion of the data.
These operations do not allocate and simply create a window over the same memory.
This significantly reduces allocations and improves performance in decoding pipelines.
Writable As Readable
Writable buffers can also expose their written content as a readable buffer without copying:
This returns a readable view over the currently written portion of the writable buffer.
Lifetime Considerations
Important
Readable views share the underlying memory.
Because of this:
- A readable view should not be retained beyond the lifetime of its source buffer.
- If data must outlive its source, explicitly materialize it:
var readableView = writable.AsReadableView();
// ...
var copy = new ReadableByteBuffer( readableView.ToArray() );
Retaining a view after the source buffer has been modified can lead to incorrect data or undefined behavior.
Writable Views
Writable buffers support bounded writable views using At( offset ).
A writable view creates a patch window over an existing region of a buffer, allowing previously written data to be modified without changing the parent buffer's cursor.
Example:
var buffer = new WritableByteBuffer();
buffer.WriteBytes( [1, 2, 3, 4, 5] );
// create a writable view starting at offset 2
// writing to the view modifies the parent buffer at the corresponding positions
var view = buffer.At( 2 )
.WriteBytes( [9, 9] );
// buffer now contains: [1, 2, 9, 9, 5]
Writable views:
- Share the same underlying memory as the parent buffer
- Maintain their own write cursor
- Are bounded to the buffer region that existed when the view was created
- Cannot extend or resize the parent buffer
Limitations
Writable views are limited to the portion of the buffer that existed when the view was created.
If the parent buffer grows later, the view cannot access or write into the newly written region.
Attempting to write beyond the view's limit will throw an exception.
Important
Writable views share the underlying memory with the parent buffer.
Because of this, a writable view should not be used after the parent buffer has been modified, as operations such as writes or resizes may invalidate the view.
Doing so may lead to unexpected behavior or data corruption.
Unsupported Operations
Writable views cannot perform operations that would change the structure of the parent buffer, including:
ClearCompact- Creating additional writable views