Class PartitionedBuffer<T>
Manages memory for unmanaged structs, storing them sequentially in contiguous memory blocks. Each struct can either be active or inactive.
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
Memory Layout Requirement: The type T must reserve its first
4 bytes (sizeof(int)) for internal bookkeeping. This memory region is used to store
the stable ID that maps the data back to its JHandle<T>.
Do not modify these bytes manually. A compatible struct should look like this:
[StructLayout(LayoutKind.Sequential)]
public struct RigidBodyData
{
private readonly int _internalIndex; // Reserved by PartitionedBuffer
public JVector Position;
public JQuaternion Orientation;
// ... other fields
}
Threading: Concurrent calls to Allocate(bool, bool) may trigger a resize. Use ResizeLock to synchronize access when reading data concurrently with allocations.
Disposal: This class owns unmanaged memory and must be disposed to avoid memory leaks.
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.
Fields
ResizeLock
Reader-writer lock. Locked by a writer when a resize occurs. Resizing moves the contiguous data memory addresses. Use a reader lock to access data if concurrent calls to Allocate are made.
public ReaderWriterLock ResizeLock
Field Value
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 amount of unmanaged memory allocated in bytes (data + indirection pages + master page table).
public long TotalBytesAllocated { get; }
Property Value
Methods
Allocate(bool, bool)
Allocates an unmanaged object. Growth is dynamic.
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
Threading: This method may resize the buffer, which moves all data. Use ResizeLock when calling concurrently with data access.
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 native structure 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>)
Retrieves the target index of 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)