Files
Misaki.HighPerformance/Misaki.HighPerformance.Test/UnitTest/Collections/TestUnsafeChunkedQueue.cs
Misaki 13802ca6c8 Job system priorities, async waits, parallel map/queue
Major refactor:
- Add job priority tiers and async wait APIs to IJobScheduler
- Implement priority-based job queues and scheduling logic
- Introduce UnsafeParallelHashMap and refactor UnsafeParallelQueue
- Refactor UnsafeSlotMap to chunked storage for scalability
- Update SlotMap/ConcurrentSlotMap for consistency and perf
- Add new benchmarks and unit tests for parallel collections
- Misc: add MemoryUtility.AlignUp, version bumps, test improvements, bug fixes
2026-04-18 11:26:08 +09:00

95 lines
2.5 KiB
C#

using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections;
namespace Misaki.HighPerformance.Test.UnitTest.Collections;
[TestClass]
public class TestUnsafeChunkedQueue
{
public TestContext TestContext
{
get;
set;
}
[TestMethod]
public void BasicEnqueueDequeueTest()
{
using var queue = new UnsafeParallelQueue<int>(32, AllocationHandle.Persistent);
Assert.IsTrue(queue.IsCreated);
queue.Enqueue(10);
queue.Enqueue(20);
Assert.IsTrue(queue.TryDequeue(out var val1));
Assert.AreEqual(10, val1);
Assert.IsTrue(queue.TryDequeue(out var val2));
Assert.AreEqual(20, val2);
Assert.IsFalse(queue.TryDequeue(out _));
}
[TestMethod]
public void ChunkExpansionTest()
{
// Force chunk expansions by enqueuing more than the chunk capacity
using var queue = new UnsafeParallelQueue<int>(16, AllocationHandle.Persistent);
var totalItems = 100;
for (var i = 0; i < totalItems; i++)
{
queue.Enqueue(i);
}
for (var i = 0; i < totalItems; i++)
{
Assert.IsTrue(queue.TryDequeue(out var val));
Assert.AreEqual(i, val);
}
Assert.IsFalse(queue.TryDequeue(out _));
}
[TestMethod]
public void ConcurrentEnqueueDequeueTest()
{
// Multi-threaded stress test to verify lock-free safety and chunk caching
using var queue = new UnsafeParallelQueue<int>(64, AllocationHandle.Persistent);
var totalElements = 100_000;
var enqueueTask = Task.Run(() =>
{
Parallel.For(0, totalElements, i =>
{
queue.Enqueue(i);
});
}, TestContext.CancellationToken);
long sum = 0;
var count = 0;
var dequeueTask = Task.Run(() =>
{
while (Volatile.Read(ref count) < totalElements)
{
if (queue.TryDequeue(out var val))
{
Interlocked.Add(ref sum, val);
Interlocked.Increment(ref count);
}
}
}, TestContext.CancellationToken);
Task.WaitAll(enqueueTask, dequeueTask);
Assert.AreEqual(totalElements, count);
// Sum of 0..N-1 is N * (N - 1) / 2
var expectedSum = (long)totalElements * (totalElements - 1) / 2;
Assert.AreEqual(expectedSum, sum);
}
}