599 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			599 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using System; | ||
|  | using NUnit.Framework; | ||
|  | using Unity.Burst; | ||
|  | using Unity.Collections; | ||
|  | using Unity.Collections.LowLevel.Unsafe; | ||
|  | using Unity.Collections.NotBurstCompatible; | ||
|  | using Unity.Jobs; | ||
|  | using Unity.Collections.Tests; | ||
|  | 
 | ||
|  | internal class NativeParallelHashSetTests: CollectionsTestFixture | ||
|  | { | ||
|  |     static void ExpectedCount<T>(ref NativeParallelHashSet<T> container, int expected) | ||
|  |         where T : unmanaged, IEquatable<T> | ||
|  |     { | ||
|  |         Assert.AreEqual(expected == 0, container.IsEmpty); | ||
|  |         Assert.AreEqual(expected, container.Count()); | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_IsEmpty() | ||
|  |     { | ||
|  |         var container = new NativeParallelHashSet<int>(0, Allocator.Persistent); | ||
|  |         Assert.IsTrue(container.IsEmpty); | ||
|  | 
 | ||
|  |         Assert.IsTrue(container.Add(0)); | ||
|  |         Assert.IsFalse(container.IsEmpty); | ||
|  |         Assert.AreEqual(1, container.Capacity); | ||
|  |         ExpectedCount(ref container, 1); | ||
|  | 
 | ||
|  |         container.Remove(0); | ||
|  |         Assert.IsTrue(container.IsEmpty); | ||
|  | 
 | ||
|  |         Assert.IsTrue(container.Add(0)); | ||
|  |         container.Clear(); | ||
|  |         Assert.IsTrue(container.IsEmpty); | ||
|  | 
 | ||
|  |         container.Dispose(); | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void UnsafeParallelHashSet_Capacity() | ||
|  |     { | ||
|  |         var container = new NativeParallelHashSet<int>(0, Allocator.Persistent); | ||
|  |         Assert.IsTrue(container.IsEmpty); | ||
|  |         Assert.AreEqual(0, container.Capacity); | ||
|  | 
 | ||
|  |         container.Capacity = 10; | ||
|  |         Assert.AreEqual(10, container.Capacity); | ||
|  | 
 | ||
|  |         container.Dispose(); | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     [TestRequiresCollectionChecks] | ||
|  |     public void NativeParallelHashSet_Full_Throws() | ||
|  |     { | ||
|  |         var container = new NativeParallelHashSet<int>(16, Allocator.Temp); | ||
|  |         ExpectedCount(ref container, 0); | ||
|  | 
 | ||
|  |         for (int i = 0, capacity = container.Capacity; i < capacity; ++i) | ||
|  |         { | ||
|  |             Assert.DoesNotThrow(() => { container.Add(i); }); | ||
|  |         } | ||
|  |         ExpectedCount(ref container, container.Capacity); | ||
|  | 
 | ||
|  |         // Make sure overallocating throws and exception if using the Concurrent version - normal hash map would grow | ||
|  |         var writer = container.AsParallelWriter(); | ||
|  |         Assert.Throws<System.InvalidOperationException>(() => { writer.Add(100); }); | ||
|  |         ExpectedCount(ref container, container.Capacity); | ||
|  | 
 | ||
|  |         container.Clear(); | ||
|  |         ExpectedCount(ref container, 0); | ||
|  | 
 | ||
|  |         container.Dispose(); | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_RemoveOnEmptyMap_DoesNotThrow() | ||
|  |     { | ||
|  |         var container = new NativeParallelHashSet<int>(0, Allocator.Temp); | ||
|  |         Assert.DoesNotThrow(() => container.Remove(0)); | ||
|  |         Assert.DoesNotThrow(() => container.Remove(-425196)); | ||
|  |         container.Dispose(); | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_Collisions() | ||
|  |     { | ||
|  |         var container = new NativeParallelHashSet<int>(16, Allocator.Temp); | ||
|  | 
 | ||
|  |         Assert.IsFalse(container.Contains(0), "Contains on empty hash map did not fail"); | ||
|  |         ExpectedCount(ref container, 0); | ||
|  | 
 | ||
|  |         // Make sure inserting values work | ||
|  |         for (int i = 0; i < 8; ++i) | ||
|  |         { | ||
|  |             Assert.IsTrue(container.Add(i), "Failed to add value"); | ||
|  |         } | ||
|  |         ExpectedCount(ref container, 8); | ||
|  | 
 | ||
|  |         // The bucket size is capacity * 2, adding that number should result in hash collisions | ||
|  |         for (int i = 0; i < 8; ++i) | ||
|  |         { | ||
|  |             Assert.IsTrue(container.Add(i + 32), "Failed to add value with potential hash collision"); | ||
|  |         } | ||
|  | 
 | ||
|  |         // Make sure reading the inserted values work | ||
|  |         for (int i = 0; i < 8; ++i) | ||
|  |         { | ||
|  |             Assert.IsTrue(container.Contains(i), "Failed get value from hash set"); | ||
|  |         } | ||
|  | 
 | ||
|  |         for (int i = 0; i < 8; ++i) | ||
|  |         { | ||
|  |             Assert.IsTrue(container.Contains(i + 32), "Failed get value from hash set"); | ||
|  |         } | ||
|  | 
 | ||
|  |         container.Dispose(); | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_SameElement() | ||
|  |     { | ||
|  |         using (var container = new NativeParallelHashSet<int>(0, Allocator.Persistent)) | ||
|  |         { | ||
|  |             Assert.IsTrue(container.Add(0)); | ||
|  |             Assert.IsFalse(container.Add(0)); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_ParallelWriter_CanBeUsedInJob() | ||
|  |     { | ||
|  |         const int count = 32; | ||
|  |         using (var hashSet = new NativeParallelHashSet<int>(count, CommonRwdAllocator.Handle)) | ||
|  |         { | ||
|  |             new ParallelWriteToHashSetJob | ||
|  |             { | ||
|  |                 Writer = hashSet.AsParallelWriter() | ||
|  |             }.Schedule(count, 2).Complete(); | ||
|  | 
 | ||
|  |             var result = hashSet.ToNativeArray(Allocator.Temp); | ||
|  |             result.Sort(); | ||
|  |             for (int i = 0; i < count; i++) | ||
|  |                 Assert.AreEqual(i, result[i]); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     struct ParallelWriteToHashSetJob : IJobParallelFor | ||
|  |     { | ||
|  |         [WriteOnly] | ||
|  |         public NativeParallelHashSet<int>.ParallelWriter Writer; | ||
|  | 
 | ||
|  |         public void Execute(int index) | ||
|  |         { | ||
|  |             Writer.Add(index); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_CanBeReadFromJob() | ||
|  |     { | ||
|  |         using (var hashSet = new NativeParallelHashSet<int>(1, CommonRwdAllocator.Handle)) | ||
|  |         using (var result = new NativeReference<int>(CommonRwdAllocator.Handle)) | ||
|  |         { | ||
|  |             hashSet.Add(42); | ||
|  |             new ReadHashSetJob | ||
|  |             { | ||
|  |                 Input = hashSet.AsReadOnly(), | ||
|  |                 Output = result, | ||
|  |             }.Run(); | ||
|  |             Assert.AreEqual(42, result.Value); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     struct TempHashSet : IJob | ||
|  |     { | ||
|  |         public void Execute() | ||
|  |         { | ||
|  |             using (var stringList = new NativeList<FixedString32Bytes>(10, Allocator.Persistent) { "Hello", ",", "World", "!" }) | ||
|  |             { | ||
|  |                 var container = new NativeParallelHashSet<FixedString128Bytes>(50, Allocator.Temp); | ||
|  |                 var seen = new NativeArray<int>(stringList.Length, Allocator.Temp); | ||
|  |                 foreach (var str in stringList) | ||
|  |                 { | ||
|  |                     container.Add(str); | ||
|  |                 } | ||
|  | 
 | ||
|  |                 foreach (var value in container) | ||
|  |                 { | ||
|  |                     int index = stringList.IndexOf(value); | ||
|  |                     Assert.AreEqual(stringList[index], value.ToString()); | ||
|  |                     seen[index] = seen[index] + 1; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 for (int i = 0; i < stringList.Length; i++) | ||
|  |                 { | ||
|  |                     Assert.AreEqual(1, seen[i], $"Incorrect value count {stringList[i]}"); | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_TempHashSetInJob() | ||
|  |     { | ||
|  |         new TempHashSet { }.Schedule().Complete(); | ||
|  |     } | ||
|  | 
 | ||
|  |     struct ReadHashSetJob : IJob | ||
|  |     { | ||
|  |         [ReadOnly] | ||
|  |         public NativeParallelHashSet<int>.ReadOnly Input; | ||
|  | 
 | ||
|  |         public NativeReference<int> Output; | ||
|  |         public void Execute() | ||
|  |         { | ||
|  |             Output.Value = Input.ToNativeArray(Allocator.Temp)[0]; | ||
|  | 
 | ||
|  |             foreach (var value in Input) | ||
|  |             { | ||
|  |                 Assert.AreEqual(42, value); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_ForEach_FixedStringInHashMap() | ||
|  |     { | ||
|  |         using (var stringList = new NativeList<FixedString32Bytes>(10, Allocator.Persistent) { "Hello", ",", "World", "!" }) | ||
|  |         { | ||
|  |             var container = new NativeParallelHashSet<FixedString128Bytes>(50, Allocator.Temp); | ||
|  |             var seen = new NativeArray<int>(stringList.Length, Allocator.Temp); | ||
|  |             foreach (var str in stringList) | ||
|  |             { | ||
|  |                 container.Add(str); | ||
|  |             } | ||
|  | 
 | ||
|  |             foreach (var value in container) | ||
|  |             { | ||
|  |                 int index = stringList.IndexOf(value); | ||
|  |                 Assert.AreEqual(stringList[index], value.ToString()); | ||
|  |                 seen[index] = seen[index] + 1; | ||
|  |             } | ||
|  | 
 | ||
|  |             for (int i = 0; i < stringList.Length; i++) | ||
|  |             { | ||
|  |                 Assert.AreEqual(1, seen[i], $"Incorrect value count {stringList[i]}"); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_ForEach([Values(10, 1000)]int n) | ||
|  |     { | ||
|  |         var seen = new NativeArray<int>(n, Allocator.Temp); | ||
|  |         using (var container = new NativeParallelHashSet<int>(32, CommonRwdAllocator.Handle)) | ||
|  |         { | ||
|  |             for (int i = 0; i < n; i++) | ||
|  |             { | ||
|  |                 container.Add(i); | ||
|  |             } | ||
|  | 
 | ||
|  |             var count = 0; | ||
|  |             foreach (var item in container) | ||
|  |             { | ||
|  |                 Assert.True(container.Contains(item)); | ||
|  |                 seen[item] = seen[item] + 1; | ||
|  |                 ++count; | ||
|  |             } | ||
|  | 
 | ||
|  |             Assert.AreEqual(container.Count(), count); | ||
|  |             for (int i = 0; i < n; i++) | ||
|  |             { | ||
|  |                 Assert.AreEqual(1, seen[i], $"Incorrect item count {i}"); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     struct NativeParallelHashSet_ForEach_Job : IJob | ||
|  |     { | ||
|  |         [ReadOnly] | ||
|  |         public NativeParallelHashSet<int>.ReadOnly Input; | ||
|  | 
 | ||
|  |         [ReadOnly] | ||
|  |         public int Num; | ||
|  | 
 | ||
|  |         public void Execute() | ||
|  |         { | ||
|  |             var seen = new NativeArray<int>(Num, Allocator.Temp); | ||
|  | 
 | ||
|  |             var count = 0; | ||
|  |             foreach (var item in Input) | ||
|  |             { | ||
|  |                 Assert.True(Input.Contains(item)); | ||
|  |                 seen[item] = seen[item] + 1; | ||
|  |                 ++count; | ||
|  |             } | ||
|  | 
 | ||
|  |             Assert.AreEqual(Input.Count(), count); | ||
|  |             for (int i = 0; i < Num; i++) | ||
|  |             { | ||
|  |                 Assert.AreEqual(1, seen[i], $"Incorrect item count {i}"); | ||
|  |             } | ||
|  | 
 | ||
|  |             seen.Dispose(); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_ForEach_From_Job([Values(10, 1000)] int n) | ||
|  |     { | ||
|  |         using (var container = new NativeParallelHashSet<int>(32, CommonRwdAllocator.Handle)) | ||
|  |         { | ||
|  |             for (int i = 0; i < n; i++) | ||
|  |             { | ||
|  |                 container.Add(i); | ||
|  |             } | ||
|  | 
 | ||
|  |             new NativeParallelHashSet_ForEach_Job | ||
|  |             { | ||
|  |                 Input = container.AsReadOnly(), | ||
|  |                 Num = n, | ||
|  | 
 | ||
|  |             }.Run(); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     [TestRequiresCollectionChecks] | ||
|  |     public void NativeParallelHashSet_ForEach_Throws_When_Modified() | ||
|  |     { | ||
|  |         using (var container = new NativeParallelHashSet<int>(32, CommonRwdAllocator.Handle)) | ||
|  |         { | ||
|  |             container.Add(0); | ||
|  |             container.Add(1); | ||
|  |             container.Add(2); | ||
|  |             container.Add(3); | ||
|  |             container.Add(4); | ||
|  |             container.Add(5); | ||
|  |             container.Add(6); | ||
|  |             container.Add(7); | ||
|  |             container.Add(8); | ||
|  |             container.Add(9); | ||
|  | 
 | ||
|  |             Assert.Throws<ObjectDisposedException>(() => | ||
|  |             { | ||
|  |                 foreach (var item in container) | ||
|  |                 { | ||
|  |                     container.Add(10); | ||
|  |                 } | ||
|  |             }); | ||
|  | 
 | ||
|  |             Assert.Throws<ObjectDisposedException>(() => | ||
|  |             { | ||
|  |                 foreach (var item in container) | ||
|  |                 { | ||
|  |                     container.Remove(1); | ||
|  |                 } | ||
|  |             }); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     [TestRequiresCollectionChecks] | ||
|  |     public void NativeParallelHashSet_ForEach_Throws() | ||
|  |     { | ||
|  |         using (var container = new NativeParallelHashSet<int>(32, CommonRwdAllocator.Handle)) | ||
|  |         { | ||
|  |             var iter = container.GetEnumerator(); | ||
|  | 
 | ||
|  |             var jobHandle = new ParallelWriteToHashSetJob | ||
|  |             { | ||
|  |                 Writer = container.AsParallelWriter() | ||
|  | 
 | ||
|  |             }.Schedule(1, 2); | ||
|  | 
 | ||
|  |             Assert.Throws<ObjectDisposedException>(() => | ||
|  |             { | ||
|  |                 while (iter.MoveNext()) | ||
|  |                 { | ||
|  |                 } | ||
|  |             }); | ||
|  | 
 | ||
|  |             jobHandle.Complete(); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     struct ForEachIterator : IJob | ||
|  |     { | ||
|  |         [ReadOnly] | ||
|  |         public NativeParallelHashSet<int>.Enumerator Iter; | ||
|  | 
 | ||
|  |         public void Execute() | ||
|  |         { | ||
|  |             while (Iter.MoveNext()) | ||
|  |             { | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     [TestRequiresCollectionChecks] | ||
|  |     public void NativeParallelHashSet_ForEach_Throws_Job_Iterator() | ||
|  |     { | ||
|  |         using (var container = new NativeParallelHashSet<int>(32, CommonRwdAllocator.Handle)) | ||
|  |         { | ||
|  |             var jobHandle = new ForEachIterator | ||
|  |             { | ||
|  |                 Iter = container.GetEnumerator() | ||
|  | 
 | ||
|  |             }.Schedule(); | ||
|  | 
 | ||
|  |             Assert.Throws<InvalidOperationException>(() => { container.Add(1); }); | ||
|  | 
 | ||
|  |             jobHandle.Complete(); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_EIU_ExceptWith_Empty() | ||
|  |     { | ||
|  |         var setA = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { }; | ||
|  |         var setB = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { }; | ||
|  |         setA.ExceptWith(setB); | ||
|  | 
 | ||
|  |         ExpectedCount(ref setA, 0); | ||
|  | 
 | ||
|  |         setA.Dispose(); | ||
|  |         setB.Dispose(); | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_EIU_ExceptWith_AxB() | ||
|  |     { | ||
|  |         var setA = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { 0, 1, 2, 3, 4, 5 }; | ||
|  |         var setB = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { 3, 4, 5, 6, 7, 8 }; | ||
|  |         setA.ExceptWith(setB); | ||
|  | 
 | ||
|  |         ExpectedCount(ref setA, 3); | ||
|  |         Assert.True(setA.Contains(0)); | ||
|  |         Assert.True(setA.Contains(1)); | ||
|  |         Assert.True(setA.Contains(2)); | ||
|  | 
 | ||
|  |         setA.Dispose(); | ||
|  |         setB.Dispose(); | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_EIU_ExceptWith_BxA() | ||
|  |     { | ||
|  |         var setA = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { 0, 1, 2, 3, 4, 5 }; | ||
|  |         var setB = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { 3, 4, 5, 6, 7, 8 }; | ||
|  |         setB.ExceptWith(setA); | ||
|  | 
 | ||
|  |         ExpectedCount(ref setB, 3); | ||
|  |         Assert.True(setB.Contains(6)); | ||
|  |         Assert.True(setB.Contains(7)); | ||
|  |         Assert.True(setB.Contains(8)); | ||
|  | 
 | ||
|  |         setA.Dispose(); | ||
|  |         setB.Dispose(); | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_EIU_IntersectWith_Empty() | ||
|  |     { | ||
|  |         var setA = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { }; | ||
|  |         var setB = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { }; | ||
|  |         setA.IntersectWith(setB); | ||
|  | 
 | ||
|  |         ExpectedCount(ref setA, 0); | ||
|  | 
 | ||
|  |         setA.Dispose(); | ||
|  |         setB.Dispose(); | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_EIU_IntersectWith() | ||
|  |     { | ||
|  |         var setA = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { 0, 1, 2, 3, 4, 5 }; | ||
|  |         var setB = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { 3, 4, 5, 6, 7, 8 }; | ||
|  |         setA.IntersectWith(setB); | ||
|  | 
 | ||
|  |         ExpectedCount(ref setA, 3); | ||
|  |         Assert.True(setA.Contains(3)); | ||
|  |         Assert.True(setA.Contains(4)); | ||
|  |         Assert.True(setA.Contains(5)); | ||
|  | 
 | ||
|  |         setA.Dispose(); | ||
|  |         setB.Dispose(); | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_EIU_UnionWith_Empty() | ||
|  |     { | ||
|  |         var setA = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { }; | ||
|  |         var setB = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { }; | ||
|  |         setA.UnionWith(setB); | ||
|  | 
 | ||
|  |         ExpectedCount(ref setA, 0); | ||
|  | 
 | ||
|  |         setA.Dispose(); | ||
|  |         setB.Dispose(); | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_EIU_UnionWith() | ||
|  |     { | ||
|  |         var setA = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { 0, 1, 2, 3, 4, 5 }; | ||
|  |         var setB = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { 3, 4, 5, 6, 7, 8 }; | ||
|  |         setA.UnionWith(setB); | ||
|  | 
 | ||
|  |         ExpectedCount(ref setA, 9); | ||
|  |         Assert.True(setA.Contains(0)); | ||
|  |         Assert.True(setA.Contains(1)); | ||
|  |         Assert.True(setA.Contains(2)); | ||
|  |         Assert.True(setA.Contains(3)); | ||
|  |         Assert.True(setA.Contains(4)); | ||
|  |         Assert.True(setA.Contains(5)); | ||
|  |         Assert.True(setA.Contains(6)); | ||
|  |         Assert.True(setA.Contains(7)); | ||
|  |         Assert.True(setA.Contains(8)); | ||
|  | 
 | ||
|  |         setA.Dispose(); | ||
|  |         setB.Dispose(); | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_ToArray() | ||
|  |     { | ||
|  |         using (var set = new NativeParallelHashSet<int>(8, CommonRwdAllocator.Handle) { 0, 1, 2, 3, 4, 5 }) | ||
|  |         { | ||
|  |             var array = set.ToArray(); | ||
|  |             Array.Sort(array); | ||
|  |             for (int i = 0, num = set.Count(); i < num; i++) | ||
|  |             { | ||
|  |                 Assert.AreEqual(array[i], i); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public void NativeParallelHashSet_CustomAllocatorTest() | ||
|  |     { | ||
|  |         AllocatorManager.Initialize(); | ||
|  |         var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent); | ||
|  |         ref var allocator = ref allocatorHelper.Allocator; | ||
|  |         allocator.Initialize(); | ||
|  | 
 | ||
|  |         using (var container = new NativeParallelHashSet<int>(1, allocator.Handle)) | ||
|  |         { | ||
|  |         } | ||
|  | 
 | ||
|  |         FastAssert.IsTrue(allocator.WasUsed); | ||
|  |         allocator.Dispose(); | ||
|  |         allocatorHelper.Dispose(); | ||
|  |         AllocatorManager.Shutdown(); | ||
|  |     } | ||
|  | 
 | ||
|  |     [BurstCompile] | ||
|  |     struct BurstedCustomAllocatorJob : IJob | ||
|  |     { | ||
|  |         [NativeDisableUnsafePtrRestriction] | ||
|  |         public unsafe CustomAllocatorTests.CountingAllocator* Allocator; | ||
|  | 
 | ||
|  |         public void Execute() | ||
|  |         { | ||
|  |             unsafe | ||
|  |             { | ||
|  |                 using (var container = new NativeParallelHashSet<int>(1, Allocator->Handle)) | ||
|  |                 { | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     [Test] | ||
|  |     public unsafe void NativeParallelHashSet_BurstedCustomAllocatorTest() | ||
|  |     { | ||
|  |         AllocatorManager.Initialize(); | ||
|  |         var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent); | ||
|  |         ref var allocator = ref allocatorHelper.Allocator; | ||
|  |         allocator.Initialize(); | ||
|  | 
 | ||
|  |         var allocatorPtr = (CustomAllocatorTests.CountingAllocator*)UnsafeUtility.AddressOf<CustomAllocatorTests.CountingAllocator>(ref allocator); | ||
|  |         unsafe | ||
|  |         { | ||
|  |             var handle = new BurstedCustomAllocatorJob {Allocator = allocatorPtr }.Schedule(); | ||
|  |             handle.Complete(); | ||
|  |         } | ||
|  | 
 | ||
|  |         FastAssert.IsTrue(allocator.WasUsed); | ||
|  |         allocator.Dispose(); | ||
|  |         allocatorHelper.Dispose(); | ||
|  |         AllocatorManager.Shutdown(); | ||
|  |     } | ||
|  | } |