Refactor memory management and improve allocation APIs

Updated `ReallocFunc` to support `oldSize`, `newSize`, and `AllocationOption`, enabling more granular control over memory reallocation. Simplified `AllocationInfo` by removing the `FreeHandler` property. Enhanced `Reallocate` and `Allocate` methods in `AllocationManager` to handle memory clearing and tracking more effectively.

Refactored `UnsafeSparseSet` to use `UnsafeArray<T>` directly, added a `generations` array, and replaced the `freeList` with `UnsafeStack<int>` for better performance and simplicity. Updated `Resize`, `Add`, and `Remove` methods to improve memory handling and code clarity.

Introduced `AllocationOption` support in `Resize` methods across `IUnsafeCollection` implementations for flexible resizing behavior. Added `GetUnsafePtr` extension methods in `UnsafeUtilities` for direct access to span data.

Added new tests for `UnsafeSparseSet` to validate resizing, clearing, enumeration, and memory compaction. These changes improve memory management, enhance performance, and ensure correctness.
This commit is contained in:
2025-10-08 15:40:49 +09:00
parent a92ab93731
commit 081103372f
14 changed files with 236 additions and 123 deletions

View File

@@ -50,4 +50,93 @@ public class TestUnsafeSparseSet
Assert.AreEqual(id, newId);
Assert.AreNotEqual(gen, newGen);
}
[TestMethod]
public unsafe void Resize()
{
const int count = 20;
var indices = stackalloc int[count];
var generations = stackalloc int[count];
for (var i = 0; i < count; i++)
{
indices[i] = _sparseSet.Add(i, out generations[i]);
}
Assert.AreEqual(count, _sparseSet.Count);
for (var i = 0; i < count; i++)
{
Assert.IsTrue(_sparseSet.Contains(indices[i], generations[i]));
}
}
[TestMethod]
public void Clear()
{
var id1 = _sparseSet.Add(10, out var gen1);
var id2 = _sparseSet.Add(20, out var gen2);
Assert.AreEqual(2, _sparseSet.Count);
_sparseSet.Clear();
Assert.AreEqual(0, _sparseSet.Count);
Assert.IsFalse(_sparseSet.Contains(id1, gen1));
Assert.IsFalse(_sparseSet.Contains(id2, gen2));
}
[TestMethod]
public unsafe void Enumerate()
{
const int count = 3;
var values = stackalloc int[count] { 10, 20, 30 };
var ids = stackalloc int[count];
var gens = stackalloc int[count];
for (var i = 0; i < count; i++)
{
ids[i] = _sparseSet.Add(values[i], out gens[i]);
}
var index = 0;
foreach (var value in _sparseSet)
{
Assert.AreEqual(values[index], value);
index++;
}
Assert.AreEqual(count, index);
}
[TestMethod]
public unsafe void MemoryCompact()
{
const int count = 3;
var values = stackalloc int[count] { 10, 20, 30 };
var ids = stackalloc int[count];
var gens = stackalloc int[count];
for (var i = 0; i < count; i++)
{
ids[i] = _sparseSet.Add(values[i], out gens[i]);
}
_sparseSet.Remove(ids[1], gens[1]); // Remove the second element (20)
var ptr = (int*)_sparseSet.GetUnsafePtr();
Assert.AreEqual(2, _sparseSet.Count);
var index = 0;
foreach (var value in _sparseSet)
{
Assert.AreEqual(ptr[index], value);
index++;
}
Assert.AreEqual(2, index);
}
}