Table of Contents

Class PartitionedBuffer<T>

Namespace
Jitter2.Unmanaged
Assembly
Jitter2.dll

Stores unmanaged structs in a resizable buffer with active and inactive partitions.

public sealed class PartitionedBuffer<T> : IDisposable where T : unmanaged

Type Parameters

T

The 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

initialSize int

The initial size of the contiguous memory block.

aligned64 bool

Indicates whether the memory should be aligned to 64 bytes.

Exceptions

ArgumentException

Thrown when T is too small to store the internal element ID.

ArgumentOutOfRangeException

Thrown when initialSize is 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

ReaderWriterLock

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

bool

Count

Gets the number of allocated elements in the buffer.

public int Count { get; }

Property Value

int

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

long

Methods

Allocate(bool, bool)

Adds an element, growing the buffer if needed.

public JHandle<T> Allocate(bool active = false, bool clear = false)

Parameters

active bool

If true, the element is added to the active partition.

clear bool

If 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

handle JHandle<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

t T

A 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

handle JHandle<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

handle JHandle<T>

The handle to check.

Returns

bool

true if the element is active; otherwise, false.

MoveToActive(JHandle<T>)

Moves an object from inactive to active.

public void MoveToActive(JHandle<T> handle)

Parameters

handle JHandle<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

handle JHandle<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)

Parameters

i int

The index of the first element.

j int

The index of the second element.