Нет описания
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

NativeParallelHashMapExtensions.cs 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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. [GenerateTestsForBurstCompatibility]
  9. public static class NativeParallelHashMapExtensions
  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. [GenerateTestsForBurstCompatibility(GenericTypeArguments = new [] { typeof(int) })]
  25. public static int Unique<T>(this NativeArray<T> array)
  26. where T : unmanaged, 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. /// <summary>
  45. /// Returns an array populated with the unique keys from this multi hash map.
  46. /// </summary>
  47. /// <typeparam name="TKey">The type of the keys.</typeparam>
  48. /// <typeparam name="TValue">The type of the values.</typeparam>
  49. /// <param name="container">The multi hash map.</param>
  50. /// <param name="allocator">The allocator to use.</param>
  51. /// <returns>An array populated with the unique keys from this multi hash map.</returns>
  52. [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(int), typeof(int) })]
  53. public static (NativeArray<TKey>, int) GetUniqueKeyArray<TKey, TValue>(this UnsafeParallelMultiHashMap<TKey, TValue> container, AllocatorManager.AllocatorHandle allocator)
  54. where TKey : unmanaged, IEquatable<TKey>, IComparable<TKey>
  55. where TValue : unmanaged
  56. {
  57. var result = container.GetKeyArray(allocator);
  58. result.Sort();
  59. int uniques = result.Unique();
  60. return (result, uniques);
  61. }
  62. /// <summary>
  63. /// Returns an array populated with the unique keys from this multi hash map.
  64. /// </summary>
  65. /// <typeparam name="TKey">The type of the keys.</typeparam>
  66. /// <typeparam name="TValue">The type of the values.</typeparam>
  67. /// <param name="container">The multi hash map.</param>
  68. /// <param name="allocator">The allocator to use.</param>
  69. /// <returns>An array populated with the unique keys from this multi hash map.</returns>
  70. [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(int), typeof(int) })]
  71. public static (NativeArray<TKey>, int) GetUniqueKeyArray<TKey, TValue>(this NativeParallelMultiHashMap<TKey, TValue> container, AllocatorManager.AllocatorHandle allocator)
  72. where TKey : unmanaged, IEquatable<TKey>, IComparable<TKey>
  73. where TValue : unmanaged
  74. {
  75. var result = container.GetKeyArray(allocator);
  76. result.Sort();
  77. int uniques = result.Unique();
  78. return (result, uniques);
  79. }
  80. /// <summary>
  81. /// Returns a "bucket" view of this hash map.
  82. /// </summary>
  83. /// <remarks>
  84. /// Internally, the elements of a hash map are split into buckets of type <see cref="UnsafeParallelHashMapBucketData"/>.
  85. ///
  86. /// With buckets, a job can safely access the elements of a hash map concurrently as long as each individual bucket is accessed
  87. /// only from an individual thread. Effectively, it is not safe to read elements of an individual bucket concurrently,
  88. /// but it is safe to read elements of separate buckets concurrently.
  89. /// </remarks>
  90. /// <typeparam name="TKey">The type of the keys.</typeparam>
  91. /// <typeparam name="TValue">The type of the values.</typeparam>
  92. /// <param name="container">The hash map.</param>
  93. /// <returns>A "bucket" view of this hash map.</returns>
  94. [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(int), typeof(int) })]
  95. public static unsafe UnsafeParallelHashMapBucketData GetUnsafeBucketData<TKey, TValue>(this NativeParallelHashMap<TKey, TValue> container)
  96. where TKey : unmanaged, IEquatable<TKey>
  97. where TValue : unmanaged
  98. {
  99. return container.m_HashMapData.m_Buffer->GetBucketData();
  100. }
  101. /// <summary>
  102. /// Returns a "bucket" view of this multi hash map.
  103. /// </summary>
  104. /// <remarks>
  105. /// Internally, the elements of a hash map are split into buckets of type <see cref="UnsafeParallelHashMapBucketData"/>.
  106. ///
  107. /// With buckets, a job can safely access the elements of a hash map concurrently as long as each individual bucket is accessed
  108. /// only from an individual thread. Effectively, it is not safe to read elements of an individual bucket concurrently,
  109. /// but it is safe to read elements of separate buckets concurrently.
  110. /// </remarks>
  111. /// <typeparam name="TKey">The type of the keys.</typeparam>
  112. /// <typeparam name="TValue">The type of the values.</typeparam>
  113. /// <param name="container">The multi hash map.</param>
  114. /// <returns>A "bucket" view of this multi hash map.</returns>
  115. [GenerateTestsForBurstCompatibility(GenericTypeArguments = new [] { typeof(int), typeof(int) })]
  116. public static unsafe UnsafeParallelHashMapBucketData GetUnsafeBucketData<TKey, TValue>(this NativeParallelMultiHashMap<TKey, TValue> container)
  117. where TKey : unmanaged, IEquatable<TKey>
  118. where TValue : unmanaged
  119. {
  120. return container.m_MultiHashMapData.m_Buffer->GetBucketData();
  121. }
  122. /// <summary>
  123. /// Removes all occurrences of a particular key-value pair.
  124. /// </summary>
  125. /// <remarks>Removes all key-value pairs which have a particular key and which *also have* a particular value.
  126. /// In other words: (key *AND* value) rather than (key *OR* value).</remarks>
  127. /// <typeparam name="TKey">The type of the keys.</typeparam>
  128. /// <typeparam name="TValue">The type of the values.</typeparam>
  129. /// <param name="container">The multi hash map.</param>
  130. /// <param name="key">The key of the key-value pairs to remove.</param>
  131. /// <param name="value">The value of the key-value pairs to remove.</param>
  132. [GenerateTestsForBurstCompatibility(GenericTypeArguments = new [] { typeof(int), typeof(int) })]
  133. public static void Remove<TKey, TValue>(this NativeParallelMultiHashMap<TKey, TValue> container, TKey key, TValue value)
  134. where TKey : unmanaged, IEquatable<TKey>
  135. where TValue : unmanaged, IEquatable<TValue>
  136. {
  137. #if ENABLE_UNITY_COLLECTIONS_CHECKS
  138. AtomicSafetyHandle.CheckWriteAndBumpSecondaryVersion(container.m_Safety);
  139. #endif
  140. container.m_MultiHashMapData.Remove(key, value);
  141. }
  142. }
  143. }