Fixed bug in ImageResultFloat
Added scoped to in TKey key
This commit is contained in:
@@ -88,14 +88,14 @@ public unsafe readonly struct ImageResultFloat : IDisposable
|
|||||||
return FromStream(stream, requiredComponents);
|
return FromStream(stream, requiredComponents);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Span<byte> AsSpan()
|
public Span<float> AsSpan()
|
||||||
{
|
{
|
||||||
if (Data == null)
|
if (Data == null)
|
||||||
{
|
{
|
||||||
return Span<byte>.Empty;
|
return Span<float>.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Span<byte>(Data, (int)Size);
|
return new Span<float>(Data, (int)Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<Authors>Misaki</Authors>
|
<Authors>Misaki</Authors>
|
||||||
<AssemblyVersion>1.1.0</AssemblyVersion>
|
<AssemblyVersion>1.1.1</AssemblyVersion>
|
||||||
<Version>$(AssemblyVersion)</Version>
|
<Version>$(AssemblyVersion)</Version>
|
||||||
<PackageProjectUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</PackageProjectUrl>
|
<PackageProjectUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</RepositoryUrl>
|
<RepositoryUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</RepositoryUrl>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Misaki.HighPerformance.LowLevel.Buffer;
|
namespace Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
@@ -291,6 +291,8 @@ public unsafe struct FreeList : IDisposable
|
|||||||
header->magicNumber = 0;
|
header->magicNumber = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIX: This may introduce ABA problem. Consider adding a version counter to the free list nodes if this becomes an issue.
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private readonly void* TryPopFromBucket(int bucketIndex)
|
private readonly void* TryPopFromBucket(int bucketIndex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private readonly int GetBucket(in TKey key)
|
private readonly int GetBucket(scoped in TKey key)
|
||||||
{
|
{
|
||||||
var h = key.GetHashCode();
|
var h = key.GetHashCode();
|
||||||
return GetBucket(h);
|
return GetBucket(h);
|
||||||
@@ -216,7 +216,7 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private int AllocateEntry(in TKey key)
|
private int AllocateEntry(scoped in TKey key)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
@@ -323,7 +323,7 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
|||||||
ResizeExact(capacity, capacity * 2);
|
ResizeExact(capacity, capacity * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Find(in TKey key)
|
public int Find(scoped in TKey key)
|
||||||
{
|
{
|
||||||
ThrowIfNotCreated();
|
ThrowIfNotCreated();
|
||||||
|
|
||||||
@@ -354,7 +354,7 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int TryAdd(in TKey key)
|
public int TryAdd(scoped in TKey key)
|
||||||
{
|
{
|
||||||
ThrowIfNotCreated();
|
ThrowIfNotCreated();
|
||||||
|
|
||||||
@@ -366,14 +366,14 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
|||||||
return AllocateEntry(key);
|
return AllocateEntry(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Add(in TKey key)
|
public int Add(scoped in TKey key)
|
||||||
{
|
{
|
||||||
ThrowIfNotCreated();
|
ThrowIfNotCreated();
|
||||||
|
|
||||||
return AllocateEntry(key);
|
return AllocateEntry(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int TryRemove(in TKey key)
|
public int TryRemove(scoped in TKey key)
|
||||||
{
|
{
|
||||||
ThrowIfNotCreated();
|
ThrowIfNotCreated();
|
||||||
|
|
||||||
@@ -425,7 +425,7 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
|||||||
return 0 != removed ? removed : -1;
|
return 0 != removed ? removed : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int RemoveAll(in TKey key)
|
public int RemoveAll(scoped in TKey key)
|
||||||
{
|
{
|
||||||
ThrowIfNotCreated();
|
ThrowIfNotCreated();
|
||||||
|
|
||||||
@@ -469,7 +469,7 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
|||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetValue<TValue>(in TKey key, out TValue item)
|
public bool TryGetValue<TValue>(scoped in TKey key, out TValue item)
|
||||||
where TValue : unmanaged
|
where TValue : unmanaged
|
||||||
{
|
{
|
||||||
ThrowIfNotCreated();
|
ThrowIfNotCreated();
|
||||||
@@ -486,7 +486,7 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int FindNext(int entryIdx, in TKey key)
|
public int FindNext(int entryIdx, scoped in TKey key)
|
||||||
{
|
{
|
||||||
ThrowIfNotCreated();
|
ThrowIfNotCreated();
|
||||||
|
|
||||||
@@ -509,7 +509,7 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CountValuesForKey(in TKey key)
|
public int CountValuesForKey(scoped in TKey key)
|
||||||
{
|
{
|
||||||
ThrowIfNotCreated();
|
ThrowIfNotCreated();
|
||||||
|
|
||||||
@@ -522,8 +522,7 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnscopedRef]
|
public ref TValue GetValueRef<TValue>(scoped in TKey key, out bool exists)
|
||||||
public ref TValue GetValueRef<TValue>(in TKey key, out bool exists)
|
|
||||||
where TValue : unmanaged
|
where TValue : unmanaged
|
||||||
{
|
{
|
||||||
ThrowIfNotCreated();
|
ThrowIfNotCreated();
|
||||||
@@ -539,8 +538,7 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
|||||||
return ref Unsafe.NullRef<TValue>();
|
return ref Unsafe.NullRef<TValue>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnscopedRef]
|
public ref TValue GetValueRefOrAddDefault<TValue>(scoped in TKey key, out bool exists)
|
||||||
public ref TValue GetValueRefOrAddDefault<TValue>(in TKey key, out bool exists)
|
|
||||||
where TValue : unmanaged
|
where TValue : unmanaged
|
||||||
{
|
{
|
||||||
ThrowIfNotCreated();
|
ThrowIfNotCreated();
|
||||||
|
|||||||
@@ -116,7 +116,8 @@ public unsafe struct UnsafeHashMap<TKey, TValue> : IUnsafeHashCollection<KeyValu
|
|||||||
/// <param name="key">The key to add.</param>
|
/// <param name="key">The key to add.</param>
|
||||||
/// <param name="item">The value to add.</param>
|
/// <param name="item">The value to add.</param>
|
||||||
/// <returns>True if the key-value pair was added.</returns>
|
/// <returns>True if the key-value pair was added.</returns>
|
||||||
public bool TryAdd(in TKey key, TValue item)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool TryAdd(scoped in TKey key, TValue item)
|
||||||
{
|
{
|
||||||
var idx = _helper.TryAdd(key);
|
var idx = _helper.TryAdd(key);
|
||||||
if (idx != -1)
|
if (idx != -1)
|
||||||
@@ -135,7 +136,8 @@ public unsafe struct UnsafeHashMap<TKey, TValue> : IUnsafeHashCollection<KeyValu
|
|||||||
/// <param name="key">The key to add.</param>
|
/// <param name="key">The key to add.</param>
|
||||||
/// <param name="item">The value to add.</param>
|
/// <param name="item">The value to add.</param>
|
||||||
/// <exception cref="ArgumentException">Thrown if the key was already present.</exception>
|
/// <exception cref="ArgumentException">Thrown if the key was already present.</exception>
|
||||||
public void Add(in TKey key, TValue item)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void Add(scoped in TKey key, TValue item)
|
||||||
{
|
{
|
||||||
var result = TryAdd(key, item);
|
var result = TryAdd(key, item);
|
||||||
if (!result)
|
if (!result)
|
||||||
@@ -149,7 +151,8 @@ public unsafe struct UnsafeHashMap<TKey, TValue> : IUnsafeHashCollection<KeyValu
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The value to remove.</param>
|
/// <param name="item">The value to remove.</param>
|
||||||
/// <returns>True if the value was present.</returns>
|
/// <returns>True if the value was present.</returns>
|
||||||
public bool Remove(in TKey key)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool Remove(scoped in TKey key)
|
||||||
{
|
{
|
||||||
return -1 != _helper.TryRemove(key);
|
return -1 != _helper.TryRemove(key);
|
||||||
}
|
}
|
||||||
@@ -160,7 +163,8 @@ public unsafe struct UnsafeHashMap<TKey, TValue> : IUnsafeHashCollection<KeyValu
|
|||||||
/// <param name="key">The key to look up.</param>
|
/// <param name="key">The key to look up.</param>
|
||||||
/// <param name="item">Outputs the value associated with the key. Outputs default if the key was not present.</param>
|
/// <param name="item">Outputs the value associated with the key. Outputs default if the key was not present.</param>
|
||||||
/// <returns>True if the key was present.</returns>
|
/// <returns>True if the key was present.</returns>
|
||||||
public bool TryGetValue(in TKey key, out TValue item)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool TryGetValue(scoped in TKey key, out TValue item)
|
||||||
{
|
{
|
||||||
return _helper.TryGetValue(key, out item);
|
return _helper.TryGetValue(key, out item);
|
||||||
}
|
}
|
||||||
@@ -171,7 +175,8 @@ public unsafe struct UnsafeHashMap<TKey, TValue> : IUnsafeHashCollection<KeyValu
|
|||||||
/// <param name="key">The key whose value to retrieve.</param>
|
/// <param name="key">The key whose value to retrieve.</param>
|
||||||
/// <param name="defaultValue">The value to return if the specified key does not exist. If not specified, the default value for the type is used.</param>
|
/// <param name="defaultValue">The value to return if the specified key does not exist. If not specified, the default value for the type is used.</param>
|
||||||
/// <returns>The value associated with the specified key if the key is found; otherwise, the specified default value.</returns>
|
/// <returns>The value associated with the specified key if the key is found; otherwise, the specified default value.</returns>
|
||||||
public TValue GetValueOrDefault(in TKey key, TValue defaultValue = default)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public TValue GetValueOrDefault(scoped in TKey key, TValue defaultValue = default)
|
||||||
{
|
{
|
||||||
if (_helper.TryGetValue<TValue>(key, out var value))
|
if (_helper.TryGetValue<TValue>(key, out var value))
|
||||||
{
|
{
|
||||||
@@ -181,14 +186,26 @@ public unsafe struct UnsafeHashMap<TKey, TValue> : IUnsafeHashCollection<KeyValu
|
|||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnscopedRef]
|
/// <summary>
|
||||||
public ref TValue GetValueRef(in TKey key, out bool exists)
|
/// Returns a reference to the value associated with the specified key, and a boolean indicating whether the key exists in the hash map.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The key whose value to retrieve.</param>
|
||||||
|
/// <param name="exists">Outputs true if the key exists in the hash map; otherwise, false.</param>
|
||||||
|
/// <returns>A reference to the value associated with the specified key.</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public ref TValue GetValueRef(scoped in TKey key, out bool exists)
|
||||||
{
|
{
|
||||||
return ref _helper.GetValueRef<TValue>(key, out exists);
|
return ref _helper.GetValueRef<TValue>(key, out exists);
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnscopedRef]
|
/// <summary>
|
||||||
public ref TValue GetValueRefOrAddDefault(in TKey key, out bool exists)
|
/// Returns a reference to the value associated with the specified key if it exists; otherwise, adds a new key with a default value and returns a reference to that value. The method also outputs a boolean indicating whether the key already existed in the hash map.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The key whose value to retrieve or add.</param>
|
||||||
|
/// <param name="exists">Outputs true if the key already existed in the hash map; otherwise, false.</param>
|
||||||
|
/// <returns>A reference to the value associated with the specified key.</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public ref TValue GetValueRefOrAddDefault(scoped in TKey key, out bool exists)
|
||||||
{
|
{
|
||||||
return ref _helper.GetValueRefOrAddDefault<TValue>(key, out exists);
|
return ref _helper.GetValueRefOrAddDefault<TValue>(key, out exists);
|
||||||
}
|
}
|
||||||
@@ -198,7 +215,8 @@ public unsafe struct UnsafeHashMap<TKey, TValue> : IUnsafeHashCollection<KeyValu
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key">The key to look up.</param>
|
/// <param name="key">The key to look up.</param>
|
||||||
/// <returns>True if the key was present.</returns>
|
/// <returns>True if the key was present.</returns>
|
||||||
public bool ContainsKey(in TKey key)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool ContainsKey(scoped in TKey key)
|
||||||
{
|
{
|
||||||
return -1 != _helper.Find(key);
|
return -1 != _helper.Find(key);
|
||||||
}
|
}
|
||||||
@@ -206,16 +224,19 @@ public unsafe struct UnsafeHashMap<TKey, TValue> : IUnsafeHashCollection<KeyValu
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the capacity to match what it would be if it had been originally initialized with all its entries.
|
/// Sets the capacity to match what it would be if it had been originally initialized with all its entries.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void TrimExcess()
|
public void TrimExcess()
|
||||||
{
|
{
|
||||||
_helper.TrimExcess();
|
_helper.TrimExcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Resize(int newSize, AllocationOption option = AllocationOption.None)
|
public void Resize(int newSize, AllocationOption option = AllocationOption.None)
|
||||||
{
|
{
|
||||||
_helper.Resize(newSize);
|
_helper.Resize(newSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
_helper.Clear();
|
_helper.Clear();
|
||||||
@@ -225,6 +246,7 @@ public unsafe struct UnsafeHashMap<TKey, TValue> : IUnsafeHashCollection<KeyValu
|
|||||||
/// Retrieves an array of keys from the hash map.
|
/// Retrieves an array of keys from the hash map.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>An array containing the keys stored in the hash map.</returns>
|
/// <returns>An array containing the keys stored in the hash map.</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public UnsafeArray<TKey> GetKeyArray(Allocator allocator)
|
public UnsafeArray<TKey> GetKeyArray(Allocator allocator)
|
||||||
{
|
{
|
||||||
return _helper.GetKeyArray(allocator);
|
return _helper.GetKeyArray(allocator);
|
||||||
@@ -234,6 +256,7 @@ public unsafe struct UnsafeHashMap<TKey, TValue> : IUnsafeHashCollection<KeyValu
|
|||||||
/// Retrieves an array of values from the underlying hash map.
|
/// Retrieves an array of values from the underlying hash map.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>An UnsafeArray containing the values stored in the hash map.</returns>
|
/// <returns>An UnsafeArray containing the values stored in the hash map.</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public UnsafeArray<TValue> GetValueArray(Allocator allocator)
|
public UnsafeArray<TValue> GetValueArray(Allocator allocator)
|
||||||
{
|
{
|
||||||
return _helper.GetValueArray<TValue>(allocator);
|
return _helper.GetValueArray<TValue>(allocator);
|
||||||
@@ -244,6 +267,7 @@ public unsafe struct UnsafeHashMap<TKey, TValue> : IUnsafeHashCollection<KeyValu
|
|||||||
/// TValue.
|
/// TValue.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Returns an UnsafeArray containing KeyValuePair objects.</returns>
|
/// <returns>Returns an UnsafeArray containing KeyValuePair objects.</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public UnsafeArray<KeyValuePair<TKey, TValue>> GetKeyValueArrays(Allocator allocator)
|
public UnsafeArray<KeyValuePair<TKey, TValue>> GetKeyValueArrays(Allocator allocator)
|
||||||
{
|
{
|
||||||
return _helper.GetKeyValueArrays<TValue>(allocator);
|
return _helper.GetKeyValueArrays<TValue>(allocator);
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ public unsafe struct UnsafeHashSet<T> : IUnsafeHashCollection<T>, IEnumerable<T>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The value to add.</param>
|
/// <param name="item">The value to add.</param>
|
||||||
/// <returns>True if the value was not already present.</returns>
|
/// <returns>True if the value was not already present.</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Add(T item)
|
public bool Add(T item)
|
||||||
{
|
{
|
||||||
return -1 != _helper.TryAdd(item);
|
return -1 != _helper.TryAdd(item);
|
||||||
@@ -96,6 +97,7 @@ public unsafe struct UnsafeHashSet<T> : IUnsafeHashCollection<T>, IEnumerable<T>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The value to remove.</param>
|
/// <param name="item">The value to remove.</param>
|
||||||
/// <returns>True if the value was present.</returns>
|
/// <returns>True if the value was present.</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Remove(T item)
|
public bool Remove(T item)
|
||||||
{
|
{
|
||||||
return -1 != _helper.TryRemove(item);
|
return -1 != _helper.TryRemove(item);
|
||||||
@@ -106,6 +108,7 @@ public unsafe struct UnsafeHashSet<T> : IUnsafeHashCollection<T>, IEnumerable<T>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The value to check for.</param>
|
/// <param name="item">The value to check for.</param>
|
||||||
/// <returns>True if the value was present.</returns>
|
/// <returns>True if the value was present.</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Contains(T item)
|
public bool Contains(T item)
|
||||||
{
|
{
|
||||||
return -1 != _helper.Find(item);
|
return -1 != _helper.Find(item);
|
||||||
@@ -114,6 +117,7 @@ public unsafe struct UnsafeHashSet<T> : IUnsafeHashCollection<T>, IEnumerable<T>
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the capacity to match what it would be if it had been originally initialized with all its entries.
|
/// Sets the capacity to match what it would be if it had been originally initialized with all its entries.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void TrimExcess()
|
public void TrimExcess()
|
||||||
{
|
{
|
||||||
_helper.TrimExcess();
|
_helper.TrimExcess();
|
||||||
@@ -124,16 +128,19 @@ public unsafe struct UnsafeHashSet<T> : IUnsafeHashCollection<T>, IEnumerable<T>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="allocator">The allocator to use.</param>
|
/// <param name="allocator">The allocator to use.</param>
|
||||||
/// <returns>An array with a copy of the set's values.</returns>
|
/// <returns>An array with a copy of the set's values.</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public UnsafeArray<T> ToNativeArray(Allocator allocator)
|
public UnsafeArray<T> ToNativeArray(Allocator allocator)
|
||||||
{
|
{
|
||||||
return _helper.GetKeyArray(allocator);
|
return _helper.GetKeyArray(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Resize(int newSize, AllocationOption option = AllocationOption.None)
|
public void Resize(int newSize, AllocationOption option = AllocationOption.None)
|
||||||
{
|
{
|
||||||
_helper.Resize(newSize);
|
_helper.Resize(newSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
_helper.Clear();
|
_helper.Clear();
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public unsafe struct UnsafeMultiHashMap<TKey, TValue> : IUnsafeHashCollection<Ke
|
|||||||
internal TKey _key;
|
internal TKey _key;
|
||||||
internal int _entryIndex;
|
internal int _entryIndex;
|
||||||
|
|
||||||
internal Iterator(in TKey key, int entryIndex)
|
internal Iterator(scoped in TKey key, int entryIndex)
|
||||||
{
|
{
|
||||||
_key = key;
|
_key = key;
|
||||||
_entryIndex = entryIndex;
|
_entryIndex = entryIndex;
|
||||||
@@ -55,7 +55,7 @@ public unsafe struct UnsafeMultiHashMap<TKey, TValue> : IUnsafeHashCollection<Ke
|
|||||||
private readonly HashMapHelper<TKey>* _data;
|
private readonly HashMapHelper<TKey>* _data;
|
||||||
private readonly TKey _key;
|
private readonly TKey _key;
|
||||||
|
|
||||||
internal ValueEnumerable(HashMapHelper<TKey>* data, in TKey key)
|
internal ValueEnumerable(HashMapHelper<TKey>* data, scoped in TKey key)
|
||||||
{
|
{
|
||||||
_data = data;
|
_data = data;
|
||||||
_key = key;
|
_key = key;
|
||||||
@@ -77,7 +77,7 @@ public unsafe struct UnsafeMultiHashMap<TKey, TValue> : IUnsafeHashCollection<Ke
|
|||||||
public readonly TValue Current => UnsafeUtility.ReadArrayElement<TValue>(_data->Buffer, _entryIndex);
|
public readonly TValue Current => UnsafeUtility.ReadArrayElement<TValue>(_data->Buffer, _entryIndex);
|
||||||
readonly object IEnumerator.Current => Current;
|
readonly object IEnumerator.Current => Current;
|
||||||
|
|
||||||
internal ValueEnumerator(HashMapHelper<TKey>* data, in TKey key)
|
internal ValueEnumerator(HashMapHelper<TKey>* data, scoped in TKey key)
|
||||||
{
|
{
|
||||||
_data = data;
|
_data = data;
|
||||||
_key = key;
|
_key = key;
|
||||||
@@ -151,18 +151,18 @@ public unsafe struct UnsafeMultiHashMap<TKey, TValue> : IUnsafeHashCollection<Ke
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(in TKey key, TValue item)
|
public void Add(scoped in TKey key, TValue item)
|
||||||
{
|
{
|
||||||
var idx = _helper.Add(key);
|
var idx = _helper.Add(key);
|
||||||
UnsafeUtility.WriteArrayElement(_helper.Buffer, idx, item);
|
UnsafeUtility.WriteArrayElement(_helper.Buffer, idx, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Remove(in TKey key)
|
public bool Remove(scoped in TKey key)
|
||||||
{
|
{
|
||||||
return _helper.RemoveAll(key) != 0;
|
return _helper.RemoveAll(key) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetFirstValue(in TKey key, out TValue item, out Iterator iterator)
|
public bool TryGetFirstValue(scoped in TKey key, out TValue item, out Iterator iterator)
|
||||||
{
|
{
|
||||||
var entryIndex = _helper.Find(key);
|
var entryIndex = _helper.Find(key);
|
||||||
if (entryIndex == -1)
|
if (entryIndex == -1)
|
||||||
@@ -198,12 +198,12 @@ public unsafe struct UnsafeMultiHashMap<TKey, TValue> : IUnsafeHashCollection<Ke
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetValue(in TKey key, out TValue item)
|
public bool TryGetValue(scoped in TKey key, out TValue item)
|
||||||
{
|
{
|
||||||
return _helper.TryGetValue(key, out item);
|
return _helper.TryGetValue(key, out item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue GetValueOrDefault(in TKey key, TValue defaultValue = default)
|
public TValue GetValueOrDefault(scoped in TKey key, TValue defaultValue = default)
|
||||||
{
|
{
|
||||||
if (_helper.TryGetValue<TValue>(key, out var value))
|
if (_helper.TryGetValue<TValue>(key, out var value))
|
||||||
{
|
{
|
||||||
@@ -213,17 +213,17 @@ public unsafe struct UnsafeMultiHashMap<TKey, TValue> : IUnsafeHashCollection<Ke
|
|||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueEnumerable GetValuesForKey(in TKey key)
|
public ValueEnumerable GetValuesForKey(scoped in TKey key)
|
||||||
{
|
{
|
||||||
return new((HashMapHelper<TKey>*)UnsafeUtility.AddressOf(ref this), key);
|
return new((HashMapHelper<TKey>*)UnsafeUtility.AddressOf(ref this), key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CountValuesForKey(in TKey key)
|
public int CountValuesForKey(scoped in TKey key)
|
||||||
{
|
{
|
||||||
return _helper.CountValuesForKey(key);
|
return _helper.CountValuesForKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ContainsKey(in TKey key)
|
public bool ContainsKey(scoped in TKey key)
|
||||||
{
|
{
|
||||||
return _helper.Find(key) != -1;
|
return _helper.Find(key) != -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Authors>Misaki</Authors>
|
<Authors>Misaki</Authors>
|
||||||
<AssemblyVersion>1.4.3</AssemblyVersion>
|
<AssemblyVersion>1.4.4</AssemblyVersion>
|
||||||
<Version>$(AssemblyVersion)</Version>
|
<Version>$(AssemblyVersion)</Version>
|
||||||
<PackageProjectUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</PackageProjectUrl>
|
<PackageProjectUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</RepositoryUrl>
|
<RepositoryUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</RepositoryUrl>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Misaki.HighPerformance.LowLevel;
|
namespace Misaki.HighPerformance.LowLevel;
|
||||||
@@ -86,7 +87,7 @@ public unsafe struct UniquePtr<T> : IEquatable<UniquePtr<T>>
|
|||||||
_value = value;
|
_value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T* Get()
|
public readonly T* Get()
|
||||||
{
|
{
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
@@ -101,6 +102,12 @@ public unsafe struct UniquePtr<T> : IEquatable<UniquePtr<T>>
|
|||||||
return new SharedPtr<T>(_value);
|
return new SharedPtr<T>(_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Attach(T* value)
|
||||||
|
{
|
||||||
|
Debug.Assert(_value == null);
|
||||||
|
_value = value;
|
||||||
|
}
|
||||||
|
|
||||||
public T* Detach()
|
public T* Detach()
|
||||||
{
|
{
|
||||||
var temp = _value;
|
var temp = _value;
|
||||||
@@ -146,6 +153,67 @@ public unsafe struct UniquePtr<T> : IEquatable<UniquePtr<T>>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[NonCopyable]
|
||||||
|
public unsafe struct DisposablePtr<T> : IDisposable, IEquatable<DisposablePtr<T>>
|
||||||
|
where T : unmanaged, IDisposable
|
||||||
|
{
|
||||||
|
private T* _value;
|
||||||
|
|
||||||
|
public DisposablePtr(T* value)
|
||||||
|
{
|
||||||
|
_value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly T* Get()
|
||||||
|
{
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref T GetRef()
|
||||||
|
{
|
||||||
|
return ref *_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly SharedPtr<T> Share()
|
||||||
|
{
|
||||||
|
return new SharedPtr<T>(_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_value != null)
|
||||||
|
{
|
||||||
|
_value->Dispose();
|
||||||
|
_value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly bool Equals(DisposablePtr<T> other)
|
||||||
|
{
|
||||||
|
return other._value == _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override readonly bool Equals(object? obj)
|
||||||
|
{
|
||||||
|
return obj is DisposablePtr<T> ptr && Equals(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override readonly int GetHashCode()
|
||||||
|
{
|
||||||
|
return ((nint)_value).GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(DisposablePtr<T> left, DisposablePtr<T> right)
|
||||||
|
{
|
||||||
|
return left.Equals(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(DisposablePtr<T> left, DisposablePtr<T> right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ref struct Ref<T> : IEquatable<Ref<T>>
|
public ref struct Ref<T> : IEquatable<Ref<T>>
|
||||||
{
|
{
|
||||||
private ref T _value;
|
private ref T _value;
|
||||||
@@ -193,23 +261,23 @@ public ref struct Ref<T> : IEquatable<Ref<T>>
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides a wrapper for a value type that implements <see cref="IDisposable"/>, ensuring proper disposal of the contained value.
|
/// Provides a wrapper for a value type that implements <see cref="IDisposable"/>, ensuring proper disposal of the contained value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>The <see cref="Owner{T}"/> class manages the lifetime of the contained value by calling its
|
/// <remarks>The <see cref="Wrapper{T}"/> class manages the lifetime of the contained value by calling its
|
||||||
/// <see cref="IDisposable.Dispose"/> method when the wrapper is disposed or finalized. After disposal, accessing the value
|
/// <see cref="IDisposable.Dispose"/> method when the wrapper is disposed or finalized. After disposal, accessing the value
|
||||||
/// will throw an <see cref="ObjectDisposedException"/>.</remarks>
|
/// will throw an <see cref="ObjectDisposedException"/>.</remarks>
|
||||||
/// <typeparam name="T">The value type to wrap. Must be a struct that implements <see cref="IDisposable"/>.</typeparam>
|
/// <typeparam name="T">The value type to wrap. Must be a struct that implements <see cref="IDisposable"/>.</typeparam>
|
||||||
public class Owner<T> : IDisposable
|
public class Wrapper<T> : IDisposable
|
||||||
where T : struct, IDisposable
|
where T : struct, IDisposable
|
||||||
{
|
{
|
||||||
private T _value;
|
private T _value;
|
||||||
|
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
public Owner(T value)
|
public Wrapper(T value)
|
||||||
{
|
{
|
||||||
_value = value;
|
_value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Owner()
|
~Wrapper()
|
||||||
{
|
{
|
||||||
Dispose();
|
Dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,19 +4,35 @@ using Misaki.HighPerformance.LowLevel.Utilities;
|
|||||||
using Misaki.HighPerformance.Mathematics.SPMD;
|
using Misaki.HighPerformance.Mathematics.SPMD;
|
||||||
using Misaki.HighPerformance.Test.Benchmark;
|
using Misaki.HighPerformance.Test.Benchmark;
|
||||||
using Misaki.HighPerformance.Test.Jobs;
|
using Misaki.HighPerformance.Test.Jobs;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
//BenchmarkRunner.Run<SPMDBenchmark>();
|
BenchmarkRunner.Run<SPMDBenchmark>();
|
||||||
var hashMap = new UnsafeHashMap<int, int>(10, Misaki.HighPerformance.LowLevel.Buffer.Allocator.Persistent);
|
//var hashMap = new UnsafeHashMap<int, int>(10, Misaki.HighPerformance.LowLevel.Buffer.Allocator.Persistent);
|
||||||
hashMap[0] = 5;
|
//hashMap[0] = 5;
|
||||||
hashMap[1] = 6;
|
//hashMap[1] = 6;
|
||||||
|
|
||||||
Console.WriteLine(hashMap[1]);
|
//Console.WriteLine(hashMap[1]);
|
||||||
|
|
||||||
ref var v = ref hashMap.GetValueRefOrAddDefault(1, out var exists);
|
//ref var v = ref hashMap.GetValueRefOrAddDefault(1, out var exists);
|
||||||
|
|
||||||
Console.WriteLine(exists);
|
//Console.WriteLine(exists);
|
||||||
|
|
||||||
v = 10;
|
//v = 10;
|
||||||
Console.WriteLine(hashMap[1]);
|
//Console.WriteLine(hashMap[1]);
|
||||||
|
|
||||||
hashMap.Dispose();
|
//hashMap.Dispose();
|
||||||
|
|
||||||
|
//class TestClass
|
||||||
|
//{
|
||||||
|
// private UnsafeHashMap<int, int> _map;
|
||||||
|
// ref int Test()
|
||||||
|
// {
|
||||||
|
// ref var x = ref _map.GetValueRef(9, out var exists);
|
||||||
|
// if (exists)
|
||||||
|
// {
|
||||||
|
// return ref x;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return ref Unsafe.NullRef<int>();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
Reference in New Issue
Block a user