A game about forced loneliness, made by TACStudios
at master 151 lines 7.7 kB view raw
1using System; 2using Unity.Collections.LowLevel.Unsafe; 3 4namespace Unity.Collections 5{ 6 /// <summary> 7 /// Provides extension methods for hash maps. 8 /// </summary> 9 [GenerateTestsForBurstCompatibility] 10 public static class NativeParallelHashMapExtensions 11 { 12 /// <summary> 13 /// Removes duplicate values from this sorted array and returns the number of values remaining. 14 /// </summary> 15 /// <remarks> 16 /// Uses `Equals` to determine whether values are duplicates. 17 /// 18 /// Expects the array to already be sorted. 19 /// 20 /// The remaining elements will be tightly packed at the front of the array. 21 /// </remarks> 22 /// <typeparam name="T">The type of values in the array.</typeparam> 23 /// <param name="array">The array from which to remove duplicates.</param> 24 /// <returns>The number of unique elements in this array.</returns> 25 [GenerateTestsForBurstCompatibility(GenericTypeArguments = new [] { typeof(int) })] 26 public static int Unique<T>(this NativeArray<T> array) 27 where T : unmanaged, IEquatable<T> 28 { 29 if (array.Length == 0) 30 { 31 return 0; 32 } 33 34 int first = 0; 35 int last = array.Length; 36 var result = first; 37 while (++first != last) 38 { 39 if (!array[result].Equals(array[first])) 40 { 41 array[++result] = array[first]; 42 } 43 } 44 45 return ++result; 46 } 47 48 /// <summary> 49 /// Returns an array populated with the unique keys from this multi hash map. 50 /// </summary> 51 /// <typeparam name="TKey">The type of the keys.</typeparam> 52 /// <typeparam name="TValue">The type of the values.</typeparam> 53 /// <param name="container">The multi hash map.</param> 54 /// <param name="allocator">The allocator to use.</param> 55 /// <returns>An array populated with the unique keys from this multi hash map.</returns> 56 [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(int), typeof(int) })] 57 public static (NativeArray<TKey>, int) GetUniqueKeyArray<TKey, TValue>(this UnsafeParallelMultiHashMap<TKey, TValue> container, AllocatorManager.AllocatorHandle allocator) 58 where TKey : unmanaged, IEquatable<TKey>, IComparable<TKey> 59 where TValue : unmanaged 60 { 61 var result = container.GetKeyArray(allocator); 62 result.Sort(); 63 int uniques = result.Unique(); 64 return (result, uniques); 65 } 66 67 /// <summary> 68 /// Returns an array populated with the unique keys from this multi hash map. 69 /// </summary> 70 /// <typeparam name="TKey">The type of the keys.</typeparam> 71 /// <typeparam name="TValue">The type of the values.</typeparam> 72 /// <param name="container">The multi hash map.</param> 73 /// <param name="allocator">The allocator to use.</param> 74 /// <returns>An array populated with the unique keys from this multi hash map.</returns> 75 [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(int), typeof(int) })] 76 public static (NativeArray<TKey>, int) GetUniqueKeyArray<TKey, TValue>(this NativeParallelMultiHashMap<TKey, TValue> container, AllocatorManager.AllocatorHandle allocator) 77 where TKey : unmanaged, IEquatable<TKey>, IComparable<TKey> 78 where TValue : unmanaged 79 { 80 var result = container.GetKeyArray(allocator); 81 result.Sort(); 82 int uniques = result.Unique(); 83 return (result, uniques); 84 } 85 86 /// <summary> 87 /// Returns a "bucket" view of this hash map. 88 /// </summary> 89 /// <remarks> 90 /// Internally, the elements of a hash map are split into buckets of type <see cref="UnsafeParallelHashMapBucketData"/>. 91 /// 92 /// With buckets, a job can safely access the elements of a hash map concurrently as long as each individual bucket is accessed 93 /// only from an individual thread. Effectively, it is not safe to read elements of an individual bucket concurrently, 94 /// but it is safe to read elements of separate buckets concurrently. 95 /// </remarks> 96 /// <typeparam name="TKey">The type of the keys.</typeparam> 97 /// <typeparam name="TValue">The type of the values.</typeparam> 98 /// <param name="container">The hash map.</param> 99 /// <returns>A "bucket" view of this hash map.</returns> 100 [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(int), typeof(int) })] 101 public static unsafe UnsafeParallelHashMapBucketData GetUnsafeBucketData<TKey, TValue>(this NativeParallelHashMap<TKey, TValue> container) 102 where TKey : unmanaged, IEquatable<TKey> 103 where TValue : unmanaged 104 { 105 return container.m_HashMapData.m_Buffer->GetBucketData(); 106 } 107 108 /// <summary> 109 /// Returns a "bucket" view of this multi hash map. 110 /// </summary> 111 /// <remarks> 112 /// Internally, the elements of a hash map are split into buckets of type <see cref="UnsafeParallelHashMapBucketData"/>. 113 /// 114 /// With buckets, a job can safely access the elements of a hash map concurrently as long as each individual bucket is accessed 115 /// only from an individual thread. Effectively, it is not safe to read elements of an individual bucket concurrently, 116 /// but it is safe to read elements of separate buckets concurrently. 117 /// </remarks> 118 /// <typeparam name="TKey">The type of the keys.</typeparam> 119 /// <typeparam name="TValue">The type of the values.</typeparam> 120 /// <param name="container">The multi hash map.</param> 121 /// <returns>A "bucket" view of this multi hash map.</returns> 122 [GenerateTestsForBurstCompatibility(GenericTypeArguments = new [] { typeof(int), typeof(int) })] 123 public static unsafe UnsafeParallelHashMapBucketData GetUnsafeBucketData<TKey, TValue>(this NativeParallelMultiHashMap<TKey, TValue> container) 124 where TKey : unmanaged, IEquatable<TKey> 125 where TValue : unmanaged 126 { 127 return container.m_MultiHashMapData.m_Buffer->GetBucketData(); 128 } 129 130 /// <summary> 131 /// Removes all occurrences of a particular key-value pair. 132 /// </summary> 133 /// <remarks>Removes all key-value pairs which have a particular key and which *also have* a particular value. 134 /// In other words: (key *AND* value) rather than (key *OR* value).</remarks> 135 /// <typeparam name="TKey">The type of the keys.</typeparam> 136 /// <typeparam name="TValue">The type of the values.</typeparam> 137 /// <param name="container">The multi hash map.</param> 138 /// <param name="key">The key of the key-value pairs to remove.</param> 139 /// <param name="value">The value of the key-value pairs to remove.</param> 140 [GenerateTestsForBurstCompatibility(GenericTypeArguments = new [] { typeof(int), typeof(int) })] 141 public static void Remove<TKey, TValue>(this NativeParallelMultiHashMap<TKey, TValue> container, TKey key, TValue value) 142 where TKey : unmanaged, IEquatable<TKey> 143 where TValue : unmanaged, IEquatable<TValue> 144 { 145#if ENABLE_UNITY_COLLECTIONS_CHECKS 146 AtomicSafetyHandle.CheckWriteAndBumpSecondaryVersion(container.m_Safety); 147#endif 148 container.m_MultiHashMapData.Remove(key, value); 149 } 150 } 151}