feat(core): add scalar ops and improve memory handling

Added scalar operator overloads for Vector types, fixed pointer math in Store methods, and improved enumerator and memory management. Updated test setup and removed allocation leak tests.

- Added left-hand scalar operator overloads for Vector2/3/4.
- Fixed pointer arithmetic in Store and GetUnsafePtr methods.
- Marked SetValue as readonly in UnsafeSparseSet.
- Improved enumerator initialization/reset for slot map and sparse set.
- Updated test projects' AssemblyVersion.
- Removed TestAllocationManager and added global AllocationManager setup/teardown.
- Updated TestConcurrentSlotMap for thread safety and correct cancellation.
- Minor formatting and parameter improvements.
This commit is contained in:
2026-04-03 00:00:09 +09:00
parent 8d5ed30c5d
commit c0580d2b46
12 changed files with 73 additions and 113 deletions

View File

@@ -1,61 +0,0 @@
using Misaki.HighPerformance.LowLevel;
using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections;
namespace Misaki.HighPerformance.Test.UnitTest.Buffer;
[TestClass]
public class TestAllocationManager
{
[TestMethod]
public void ShouldNotLeakTest()
{
try
{
var array = new UnsafeArray<int>(10, Allocator.Persistent);
var array2 = new UnsafeArray<int>(10, Allocator.Persistent);
array.Dispose();
array2.Dispose();
AllocationManager.Dispose();
}
finally
{
#if MHP_ENABLE_SAFETY_CHECKS
var leaks = AllocationManager.LiveAllocationCount;
Assert.AreEqual(0, leaks);
#endif
}
}
[TestMethod]
public void ShouldLeakTest()
{
var array = new UnsafeArray<int>(10, Allocator.Persistent);
var array2 = new UnsafeArray<int>(10, Allocator.Persistent);
try
{
AllocationManager.Dispose();
}
catch (MemoryLeakException)
{
#if MHP_ENABLE_SAFETY_CHECKS
var leaks = AllocationManager.LiveAllocationCount;
Assert.AreEqual(2, leaks);
#endif
return;
}
finally
{
array.Dispose();
array2.Dispose();
}
#if ENABLE_SAFETY_CHECKS
Assert.Fail("Expected MemoryLeakException was not thrown.");
#endif
}
}

View File

@@ -4,6 +4,7 @@ using System.Collections.Concurrent;
namespace Misaki.HighPerformance.Test.UnitTest.Collections;
[TestClass]
[DoNotParallelize]
public class TestConcurrentSlotMap
{
private ConcurrentSlotMap<int> _slotMap = null!;
@@ -79,10 +80,10 @@ public class TestConcurrentSlotMap
{
_slotMap.Add(i, out _);
}
}, TestContext.CancellationTokenSource.Token));
}, TestContext.CancellationToken));
}
Task.WaitAll(tasks, TestContext.CancellationTokenSource.Token);
Task.WaitAll(tasks, TestContext.CancellationToken);
Assert.AreEqual(threadCount * itemsPerThread, _slotMap.Count);
}
@@ -93,7 +94,6 @@ public class TestConcurrentSlotMap
const int operationsPerThread = 1000;
var tasks = new List<Task>();
var rand = new Random();
var addedItems = new ConcurrentBag<(int slotIndex, int generation)>();
var count = 0;
@@ -104,7 +104,7 @@ public class TestConcurrentSlotMap
{
for (var i = 0; i < operationsPerThread; i++)
{
if (rand.NextDouble() < 0.5)
if (Random.Shared.NextDouble() < 0.5)
{
var slotIndex = _slotMap.Add(i, out var generation);
addedItems.Add((slotIndex, generation));
@@ -113,14 +113,16 @@ public class TestConcurrentSlotMap
}
else if (addedItems.TryTake(out var item))
{
_slotMap.Remove(item.slotIndex, item.generation);
Interlocked.Decrement(ref count);
if (_slotMap.Remove(item.slotIndex, item.generation))
{
Interlocked.Decrement(ref count);
}
}
}
}, TestContext.CancellationTokenSource.Token));
}, TestContext.CancellationToken));
}
Task.WaitAll(tasks, TestContext.CancellationTokenSource.Token);
Task.WaitAll(tasks, TestContext.CancellationToken);
Assert.AreEqual(count, _slotMap.Count);
}

View File

@@ -0,0 +1,19 @@
using Misaki.HighPerformance.LowLevel.Buffer;
namespace Misaki.HighPerformance.Test.UnitTest;
[TestClass]
public static class GlobalSetup
{
[GlobalTestInitialize]
public static void GlobalInitialize(TestContext ctx)
{
AllocationManager.Initialize(AllocationManagerInitOpts.Default);
}
[GlobalTestCleanup]
public static void GlobalCleanup(TestContext ctx)
{
AllocationManager.Dispose();
}
}