Class PartitionedBuffer<T>
Stores unmanaged structs in a resizable buffer with active and inactive partitions.
public sealed class PartitionedBuffer<T> : IDisposable where T : unmanaged
Type Parameters
TThe unmanaged type to store. Must be at least 4 bytes in size.
- Inheritance
-
PartitionedBuffer<T>
- Implements
- Inherited Members
- Extension Methods
Remarks
Reserve the first 4 bytes of T for the buffer's element ID.
Do not overwrite these bytes. Place an integer at offset zero, for example as the first field
of a sequential layout:
[StructLayout(LayoutKind.Sequential)]
public struct MyData
{
private readonly int _index; // Reserved by PartitionedBuffer
public JVector Position;
public JQuaternion Orientation;
// ... other fields
}
Do not modify the buffer concurrently. Readers that may run during an allocation must hold a read lock on ResizeLock. This protects against resizing only; callers must also prevent reads from conflicting with element moves or writes.
Dispose the buffer when it is no longer needed to release its unmanaged memory.
Constructors
PartitionedBuffer(int, bool)
Initializes a new instance of the class.
public PartitionedBuffer(int initialSize = 1024, bool aligned64 = false)
Parameters
initialSizeintThe initial size of the contiguous memory block.
aligned64boolIndicates whether the memory should be aligned to 64 bytes.
Exceptions
- ArgumentException
Thrown when
Tis too small to store the internal element ID.- ArgumentOutOfRangeException
Thrown when
initialSizeis less than one or exceeds the maximum capacity.
Fields
ResizeLock
Protects data access while an allocation may resize the buffer.
public readonly ReaderWriterLock ResizeLock
Field Value
Remarks
Acquire a read lock before accessing data concurrently with Allocate(bool, bool).
Properties
Active
A span for all elements marked as active.
public Span<T> Active { get; }
Property Value
- Span<T>
Remarks
Do not cache: This span is invalidated when the buffer resizes.
Aligned64
Indicates whether the allocated memory is aligned to a 64-byte boundary.
public bool Aligned64 { get; }
Property Value
Count
Gets the number of allocated elements in the buffer.
public int Count { get; }
Property Value
Elements
A span for all elements.
public Span<T> Elements { get; }
Property Value
- Span<T>
Remarks
Do not cache: This span is invalidated when the buffer resizes.
Inactive
A span for all elements marked as inactive.
public Span<T> Inactive { get; }
Property Value
- Span<T>
Remarks
Do not cache: This span is invalidated when the buffer resizes.
TotalBytesAllocated
Returns the total number of bytes of unmanaged memory owned by the buffer, including handle storage.
public long TotalBytesAllocated { get; }
Property Value
Methods
Allocate(bool, bool)
Adds an element, growing the buffer if needed.
public JHandle<T> Allocate(bool active = false, bool clear = false)
Parameters
activeboolIf true, the element is added to the active partition.
clearboolIf true, the element's memory (excluding the internal ID) is zeroed.
Returns
- JHandle<T>
A handle to the newly allocated element.
Remarks
Do not call concurrently with other modifications. This method can move existing elements; obtain fresh data references afterward. Use ResizeLock to protect concurrent readers against resizing.
Exceptions
- PartitionedBuffer<T>.MaximumSizeException
Thrown when the internal indirection table limit is reached.
Dispose()
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
public void Dispose()
~PartitionedBuffer()
protected ~PartitionedBuffer()
Free(JHandle<T>)
Removes the associated unmanaged element from the buffer and invalidates the handle.
public void Free(JHandle<T> handle)
Parameters
handleJHandle<T>The handle to free.
Remarks
Safety: After calling this method, the handle becomes invalid. Do not use the handle or any cached references to its data.
GetHandle(ref T)
Returns the handle of the object. O(1) operation.
public JHandle<T> GetHandle(ref T t)
Parameters
tTA reference to the element in the buffer.
Returns
- JHandle<T>
The handle for the element.
GetIndex(JHandle<T>)
Gets the index of the element referred to by the handle.
public int GetIndex(JHandle<T> handle)
Parameters
handleJHandle<T>The handle to get the index for.
Returns
- int
The index of the element in the buffer.
IsActive(JHandle<T>)
Checks if the element is stored as an active element. O(1).
public bool IsActive(JHandle<T> handle)
Parameters
handleJHandle<T>The handle to check.
Returns
MoveToActive(JHandle<T>)
Moves an object from inactive to active.
public void MoveToActive(JHandle<T> handle)
Parameters
handleJHandle<T>The handle of the element to move.
MoveToInactive(JHandle<T>)
Moves an object from active to inactive.
public void MoveToInactive(JHandle<T> handle)
Parameters
handleJHandle<T>The handle of the element to move.
Swap(int, int)
Swap two entries based on their index. Adjusts handles accordingly.
public void Swap(int i, int j)