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:
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user