No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

NativeHashMapExtensions.cs 8.7KB

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