using System;
using Unity.Collections.LowLevel.Unsafe;
namespace Unity.Collections
{
///
/// Provides extension methods for hash maps.
///
[GenerateTestsForBurstCompatibility]
public static class NativeParallelHashMapExtensions
{
///
/// Removes duplicate values from this sorted array and returns the number of values remaining.
///
///
/// Uses `Equals` to determine whether values are duplicates.
///
/// Expects the array to already be sorted.
///
/// The remaining elements will be tightly packed at the front of the array.
///
/// The type of values in the array.
/// The array from which to remove duplicates.
/// The number of unique elements in this array.
[GenerateTestsForBurstCompatibility(GenericTypeArguments = new [] { typeof(int) })]
public static int Unique(this NativeArray array)
where T : unmanaged, IEquatable
{
if (array.Length == 0)
{
return 0;
}
int first = 0;
int last = array.Length;
var result = first;
while (++first != last)
{
if (!array[result].Equals(array[first]))
{
array[++result] = array[first];
}
}
return ++result;
}
///
/// Returns an array populated with the unique keys from this multi hash map.
///
/// The type of the keys.
/// The type of the values.
/// The multi hash map.
/// The allocator to use.
/// An array populated with the unique keys from this multi hash map.
[GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(int), typeof(int) })]
public static (NativeArray, int) GetUniqueKeyArray(this UnsafeParallelMultiHashMap container, AllocatorManager.AllocatorHandle allocator)
where TKey : unmanaged, IEquatable, IComparable
where TValue : unmanaged
{
var result = container.GetKeyArray(allocator);
result.Sort();
int uniques = result.Unique();
return (result, uniques);
}
///
/// Returns an array populated with the unique keys from this multi hash map.
///
/// The type of the keys.
/// The type of the values.
/// The multi hash map.
/// The allocator to use.
/// An array populated with the unique keys from this multi hash map.
[GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(int), typeof(int) })]
public static (NativeArray, int) GetUniqueKeyArray(this NativeParallelMultiHashMap container, AllocatorManager.AllocatorHandle allocator)
where TKey : unmanaged, IEquatable, IComparable
where TValue : unmanaged
{
var result = container.GetKeyArray(allocator);
result.Sort();
int uniques = result.Unique();
return (result, uniques);
}
///
/// Returns a "bucket" view of this hash map.
///
///
/// Internally, the elements of a hash map are split into buckets of type .
///
/// With buckets, a job can safely access the elements of a hash map concurrently as long as each individual bucket is accessed
/// only from an individual thread. Effectively, it is not safe to read elements of an individual bucket concurrently,
/// but it is safe to read elements of separate buckets concurrently.
///
/// The type of the keys.
/// The type of the values.
/// The hash map.
/// A "bucket" view of this hash map.
[GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] { typeof(int), typeof(int) })]
public static unsafe UnsafeParallelHashMapBucketData GetUnsafeBucketData(this NativeParallelHashMap container)
where TKey : unmanaged, IEquatable
where TValue : unmanaged
{
return container.m_HashMapData.m_Buffer->GetBucketData();
}
///
/// Returns a "bucket" view of this multi hash map.
///
///
/// Internally, the elements of a hash map are split into buckets of type .
///
/// With buckets, a job can safely access the elements of a hash map concurrently as long as each individual bucket is accessed
/// only from an individual thread. Effectively, it is not safe to read elements of an individual bucket concurrently,
/// but it is safe to read elements of separate buckets concurrently.
///
/// The type of the keys.
/// The type of the values.
/// The multi hash map.
/// A "bucket" view of this multi hash map.
[GenerateTestsForBurstCompatibility(GenericTypeArguments = new [] { typeof(int), typeof(int) })]
public static unsafe UnsafeParallelHashMapBucketData GetUnsafeBucketData(this NativeParallelMultiHashMap container)
where TKey : unmanaged, IEquatable
where TValue : unmanaged
{
return container.m_MultiHashMapData.m_Buffer->GetBucketData();
}
///
/// Removes all occurrences of a particular key-value pair.
///
/// Removes all key-value pairs which have a particular key and which *also have* a particular value.
/// In other words: (key *AND* value) rather than (key *OR* value).
/// The type of the keys.
/// The type of the values.
/// The multi hash map.
/// The key of the key-value pairs to remove.
/// The value of the key-value pairs to remove.
[GenerateTestsForBurstCompatibility(GenericTypeArguments = new [] { typeof(int), typeof(int) })]
public static void Remove(this NativeParallelMultiHashMap container, TKey key, TValue value)
where TKey : unmanaged, IEquatable
where TValue : unmanaged, IEquatable
{
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckWriteAndBumpSecondaryVersion(container.m_Safety);
#endif
container.m_MultiHashMapData.Remove(key, value);
}
}
}