using Sandbox.Utility;
namespace TestSystem.Collections;
[TestClass]
public class HashSetExTest
{
///
/// Additions to a while enumerating it must be
/// deferred until after the enumeration.
///
[TestMethod]
[DataRow( 1_000 )]
[DataRow( 10_000 )]
[DataRow( 100_000 )]
[DataRow( 1_000_000 )]
public void DeferredAdd( int itemCount )
{
var hashSet = new HashSetEx();
for ( var i = 0; i < itemCount; ++i )
{
hashSet.Add( i );
}
Assert.AreEqual( itemCount, hashSet.Count );
var enumeratedCount = 0;
foreach ( var item in hashSet.EnumerateLocked() )
{
// Test item < itemCount here to avoid endless loop if EnumerateLocked doesn't work
if ( item < itemCount )
{
hashSet.Add( item + itemCount );
}
enumeratedCount++;
}
Assert.AreEqual( itemCount, enumeratedCount );
Assert.AreEqual( itemCount * 2, hashSet.Count );
}
///
/// Removals from a while enumerating it must be
/// deferred until after the enumeration.
///
[TestMethod]
[DataRow( 1_000 )]
[DataRow( 10_000 )]
[DataRow( 100_000 )]
[DataRow( 1_000_000 )]
public void DeferredRemove( int itemCount )
{
var hashSet = new HashSetEx();
for ( var i = 0; i < itemCount; ++i )
{
hashSet.Add( i );
}
Assert.AreEqual( itemCount, hashSet.Count );
foreach ( var item in hashSet.EnumerateLocked() )
{
hashSet.Remove( item );
}
Assert.AreEqual( 0, hashSet.Count );
}
///
/// Stress test iterating variously sized 1,000 times, with
/// the set being modified between each iteration.
///
[TestMethod]
[DataRow( 1_000, 1_000 )]
[DataRow( 10_000, 1_000 )]
[DataRow( 100_000, 1_000 )]
[DataRow( 1_000_000, 1_000 )]
public void WorstCaseIteration( int itemCount, int iterations )
{
var hashSet = new HashSetEx();
for ( var i = 0; i < itemCount; ++i )
{
hashSet.Add( i );
}
for ( var i = 0; i < iterations; ++i )
{
Assert.AreEqual( itemCount, hashSet.Count );
var sum = 0;
foreach ( var item in hashSet.EnumerateLocked() )
{
sum += item;
}
// Force list to dirty
hashSet.Add( -1 );
hashSet.Remove( -1 );
}
}
}