Add SparseSet Test
This commit is contained in:
@@ -4,14 +4,20 @@ using System.Collections.Concurrent;
|
||||
namespace Misaki.HighPerformance.Test.UnitTest.Collections;
|
||||
|
||||
[TestClass]
|
||||
public class TestSlotMap
|
||||
public class TestConcurrentSlotMap
|
||||
{
|
||||
private SlotMap<int> _slotMap = null!;
|
||||
private ConcurrentSlotMap<int> _slotMap = null!;
|
||||
|
||||
public TestContext TestContext
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
_slotMap = new SlotMap<int>();
|
||||
_slotMap = new ConcurrentSlotMap<int>();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -57,4 +63,65 @@ public class TestSlotMap
|
||||
Assert.AreEqual(slotIndex1, slotIndex2);
|
||||
Assert.AreNotEqual(generation1, generation2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestConcurrentAdditions()
|
||||
{
|
||||
const int threadCount = 8;
|
||||
const int itemsPerThread = 1000;
|
||||
var tasks = new List<Task>();
|
||||
|
||||
for (int t = 0; t < threadCount; t++)
|
||||
{
|
||||
tasks.Add(Task.Run(() =>
|
||||
{
|
||||
for (int i = 0; i < itemsPerThread; i++)
|
||||
{
|
||||
_slotMap.Add(i, out _);
|
||||
}
|
||||
}, TestContext.CancellationTokenSource.Token));
|
||||
}
|
||||
|
||||
Task.WaitAll(tasks, TestContext.CancellationTokenSource.Token);
|
||||
Assert.AreEqual(threadCount * itemsPerThread, _slotMap.Count);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestConcurrentRandomAddRemove()
|
||||
{
|
||||
const int threadCount = 8;
|
||||
const int operationsPerThread = 1000;
|
||||
|
||||
var tasks = new List<Task>();
|
||||
var rand = new Random();
|
||||
var addedItems = new ConcurrentBag<(int slotIndex, int generation)>();
|
||||
|
||||
var count = 0;
|
||||
|
||||
for (int t = 0; t < threadCount; t++)
|
||||
{
|
||||
tasks.Add(Task.Run(() =>
|
||||
{
|
||||
for (int i = 0; i < operationsPerThread; i++)
|
||||
{
|
||||
if (rand.NextDouble() < 0.5)
|
||||
{
|
||||
var slotIndex = _slotMap.Add(i, out var generation);
|
||||
addedItems.Add((slotIndex, generation));
|
||||
|
||||
Interlocked.Increment(ref count);
|
||||
}
|
||||
else if (addedItems.TryTake(out var item))
|
||||
{
|
||||
_slotMap.Remove(item.slotIndex, item.generation);
|
||||
Interlocked.Decrement(ref count);
|
||||
}
|
||||
}
|
||||
}, TestContext.CancellationTokenSource.Token));
|
||||
}
|
||||
|
||||
Task.WaitAll(tasks, TestContext.CancellationTokenSource.Token);
|
||||
|
||||
Assert.AreEqual(count, _slotMap.Count);
|
||||
}
|
||||
}
|
||||
@@ -4,20 +4,14 @@ using System.Collections.Concurrent;
|
||||
namespace Misaki.HighPerformance.Test.UnitTest.Collections;
|
||||
|
||||
[TestClass]
|
||||
public class TestConcurrentSlotMap
|
||||
public class TestSlotMap
|
||||
{
|
||||
private ConcurrentSlotMap<int> _slotMap = null!;
|
||||
|
||||
public TestContext TestContext
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
private SlotMap<int> _slotMap = null!;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
_slotMap = new ConcurrentSlotMap<int>();
|
||||
_slotMap = new SlotMap<int>();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -63,65 +57,4 @@ public class TestConcurrentSlotMap
|
||||
Assert.AreEqual(slotIndex1, slotIndex2);
|
||||
Assert.AreNotEqual(generation1, generation2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestConcurrentAdditions()
|
||||
{
|
||||
const int threadCount = 8;
|
||||
const int itemsPerThread = 1000;
|
||||
var tasks = new List<Task>();
|
||||
|
||||
for (int t = 0; t < threadCount; t++)
|
||||
{
|
||||
tasks.Add(Task.Run(() =>
|
||||
{
|
||||
for (int i = 0; i < itemsPerThread; i++)
|
||||
{
|
||||
_slotMap.Add(i, out _);
|
||||
}
|
||||
}, TestContext.CancellationTokenSource.Token));
|
||||
}
|
||||
|
||||
Task.WaitAll(tasks, TestContext.CancellationTokenSource.Token);
|
||||
Assert.AreEqual(threadCount * itemsPerThread, _slotMap.Count);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestConcurrentRandomAddRemove()
|
||||
{
|
||||
const int threadCount = 8;
|
||||
const int operationsPerThread = 1000;
|
||||
|
||||
var tasks = new List<Task>();
|
||||
var rand = new Random();
|
||||
var addedItems = new ConcurrentBag<(int slotIndex, int generation)>();
|
||||
|
||||
var count = 0;
|
||||
|
||||
for (int t = 0; t < threadCount; t++)
|
||||
{
|
||||
tasks.Add(Task.Run(() =>
|
||||
{
|
||||
for (int i = 0; i < operationsPerThread; i++)
|
||||
{
|
||||
if (rand.NextDouble() < 0.5)
|
||||
{
|
||||
var slotIndex = _slotMap.Add(i, out var generation);
|
||||
addedItems.Add((slotIndex, generation));
|
||||
|
||||
Interlocked.Increment(ref count);
|
||||
}
|
||||
else if (addedItems.TryTake(out var item))
|
||||
{
|
||||
_slotMap.Remove(item.slotIndex, item.generation);
|
||||
Interlocked.Decrement(ref count);
|
||||
}
|
||||
}
|
||||
}, TestContext.CancellationTokenSource.Token));
|
||||
}
|
||||
|
||||
Task.WaitAll(tasks, TestContext.CancellationTokenSource.Token);
|
||||
|
||||
Assert.AreEqual(count, _slotMap.Count);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using Misaki.HighPerformance.Collections;
|
||||
|
||||
namespace Misaki.HighPerformance.Test.UnitTest.Collections;
|
||||
|
||||
[TestClass]
|
||||
public class TestSparseSet
|
||||
{
|
||||
private SparseSet<int> _sparseSet = null!;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
_sparseSet = new SparseSet<int>(16);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InvalidID()
|
||||
{
|
||||
Assert.IsFalse(_sparseSet.Contains(0, 0));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Add()
|
||||
{
|
||||
var id = _sparseSet.Add(10, out var gen);
|
||||
Assert.IsTrue(_sparseSet.Contains(id, gen));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Remove()
|
||||
{
|
||||
var id = _sparseSet.Add(20, out var gen);
|
||||
Assert.IsTrue(_sparseSet.Contains(id, gen));
|
||||
|
||||
_sparseSet.Remove(id, gen);
|
||||
Assert.IsFalse(_sparseSet.Contains(id, gen));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IndexReuse()
|
||||
{
|
||||
var id = _sparseSet.Add(20, out var gen);
|
||||
Assert.IsTrue(_sparseSet.Contains(id, gen));
|
||||
|
||||
_sparseSet.Remove(id, gen);
|
||||
Assert.IsFalse(_sparseSet.Contains(id, gen));
|
||||
|
||||
var newId = _sparseSet.Add(30, out var newGen);
|
||||
Assert.AreEqual(id, newId);
|
||||
Assert.AreNotEqual(gen, newGen);
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,12 @@ public class TestUnsafeSparseSet
|
||||
_sparseSet.Dispose();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InvalidID()
|
||||
{
|
||||
Assert.IsFalse(_sparseSet.Contains(0, 0));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Add()
|
||||
{
|
||||
@@ -139,4 +145,4 @@ public class TestUnsafeSparseSet
|
||||
|
||||
Assert.AreEqual(2, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user