diff --git a/Misaki.HighPerformance.LowLevel/Misaki.HighPerformance.LowLevel.csproj b/Misaki.HighPerformance.LowLevel/Misaki.HighPerformance.LowLevel.csproj
index 611e7c2..a289b17 100644
--- a/Misaki.HighPerformance.LowLevel/Misaki.HighPerformance.LowLevel.csproj
+++ b/Misaki.HighPerformance.LowLevel/Misaki.HighPerformance.LowLevel.csproj
@@ -7,7 +7,7 @@
true
true
Misaki
- 1.3.8
+ 1.3.9
$(AssemblyVersion)
https://git.personalnas.com/Misaki/Misaki.HighPerformance.git
https://git.personalnas.com/Misaki/Misaki.HighPerformance.git
diff --git a/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Utilities/HashMapHelper.cs b/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/HashMapHelper.cs
similarity index 99%
rename from Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Utilities/HashMapHelper.cs
rename to Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/HashMapHelper.cs
index 3be76d4..ac3c96f 100644
--- a/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Utilities/HashMapHelper.cs
+++ b/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/HashMapHelper.cs
@@ -1,10 +1,10 @@
using Misaki.HighPerformance.LowLevel.Buffer;
-using Misaki.HighPerformance.LowLevel.Collections;
+using Misaki.HighPerformance.LowLevel.Utilities;
using System.Diagnostics;
using System.Numerics;
using System.Runtime.CompilerServices;
-namespace Misaki.HighPerformance.LowLevel.Utilities;
+namespace Misaki.HighPerformance.LowLevel.Collections;
public unsafe struct HashMapHelper : IDisposable
where TKey : unmanaged, IEquatable
diff --git a/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/UnsafeList.cs b/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/UnsafeList.cs
index 79c4871..4b8a5c5 100644
--- a/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/UnsafeList.cs
+++ b/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/UnsafeList.cs
@@ -79,6 +79,8 @@ public unsafe struct UnsafeList : IUnsafeCollection
///
public unsafe struct ParallelWriter
{
+ private volatile int _resizeLock;
+
///
/// The UnsafeList to write to.
///
@@ -259,22 +261,20 @@ public unsafe struct UnsafeList : IUnsafeCollection
/// Adds a range of elements to the collection.
///
/// A span containing the elements to add. The span must not exceed the specified .
- /// The number of elements to add from the span. Must be non-negative and less than or
- /// equal to the length of .
- public void AddRange(Span values, int count)
+ public void AddRange(Span values)
{
- var newSize = _count + count;
+ var newSize = _count + values.Length;
if (newSize > Capacity)
{
- Resize(Capacity + count);
+ Resize(Capacity + values.Length);
}
fixed (T* ptr = values)
{
- MemCpy(UnsafeUtility.ReadArrayElementUnsafe(_array.GetUnsafePtr(), _count), ptr, (uint)(count * sizeof(T)));
+ MemCpy(UnsafeUtility.ReadArrayElementUnsafe(_array.GetUnsafePtr(), _count), ptr, (uint)(values.Length * sizeof(T)));
}
- _count += count;
+ _count += values.Length;
}
///
diff --git a/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/UnsafeSlotMap.cs b/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/UnsafeSlotMap.cs
index ecd0f3a..c8a11d9 100644
--- a/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/UnsafeSlotMap.cs
+++ b/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/UnsafeSlotMap.cs
@@ -176,11 +176,12 @@ public unsafe struct UnsafeSlotMap : IUnsafeCollection
/// Attempts to remove the item at the specified slot index and generation from the collection.
///
/// The zero-based index of the slot to remove. Must be within the valid range of slot indices.
- /// The generation value associated with the slot. Removal succeeds only if this matches the current generation of
- /// the slot.
+ /// The generation value associated with the slot. Removal succeeds only if this matches the current generation of the slot.
+ /// When this method returns, contains the item that was removed if the removal was successful; otherwise, the default value for type .
/// true if the item was successfully removed; otherwise, false.
- public bool Remove(int slotIndex, int generation)
+ public bool Remove(int slotIndex, int generation, out T item)
{
+ item = default;
if (slotIndex < 0 || slotIndex >= _capacity)
{
return false;
@@ -192,6 +193,8 @@ public unsafe struct UnsafeSlotMap : IUnsafeCollection
return false;
}
+ item = _data[slotIndex];
+
gen++;
_validBits.ClearBit(slotIndex);
_freeSlots.Enqueue(slotIndex);
@@ -201,6 +204,18 @@ public unsafe struct UnsafeSlotMap : IUnsafeCollection
return true;
}
+ ///
+ /// Attempts to remove the item at the specified slot index and generation from the collection.
+ ///
+ /// The zero-based index of the slot to remove. Must be within the valid range of slot indices.
+ /// The generation value associated with the slot. Removal succeeds only if this matches the current generation of
+ /// the slot.
+ /// true if the item was successfully removed; otherwise, false.
+ public bool Remove(int slotIndex, int generation)
+ {
+ return Remove(slotIndex, generation, out _);
+ }
+
///
/// Determines whether the specified slot index contains a valid entry with the given generation.
///
diff --git a/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/UnsafeSparseSet.cs b/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/UnsafeSparseSet.cs
index e8bb1ca..282db52 100644
--- a/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/UnsafeSparseSet.cs
+++ b/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/Collections/UnsafeSparseSet.cs
@@ -190,6 +190,49 @@ public unsafe struct UnsafeSparseSet : IUnsafeCollection
return sparseIndex;
}
+ ///
+ /// Removes the value at the specified sparse index.
+ ///
+ /// The sparse index of the value to remove.
+ /// The generation number associated with the sparse index to validate.
+ /// When this method returns, contains the item that was removed if the removal was successful; otherwise, the default value for type .
+ /// True if the value was removed, false if the sparse index was not found.
+ public bool Remove(int sparseIndex, int generation, out T item)
+ {
+ item = default;
+ if (!Contains(sparseIndex, generation))
+ {
+ return false;
+ }
+
+ var denseIndex = _sparse[sparseIndex];
+ var lastIndex = _count - 1;
+
+ if (denseIndex != lastIndex)
+ {
+ // Move the last element to the position of the removed element
+ var lastValue = _dense[lastIndex];
+ var lastSparseIndex = _reverse[lastIndex]; // Get sparse index of last element
+
+ _dense[denseIndex] = lastValue;
+ _reverse[denseIndex] = lastSparseIndex;
+
+ // Update the sparse mapping for the moved element
+ _sparse[lastSparseIndex] = denseIndex;
+ }
+
+ // Mark the sparse index as unused and add to free list
+ _sparse[sparseIndex] = -1;
+ _generations[sparseIndex]++; // Increment generation to invalidate old references
+
+ item = _dense[denseIndex];
+
+ _freeSparse.Push(sparseIndex);
+ _count--;
+
+ return true;
+ }
+
///
/// Removes the value at the specified sparse index.
///
diff --git a/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/MemoryLeakException.cs b/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/MemoryLeakException.cs
index a07ec28..5dfd62b 100644
--- a/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/MemoryLeakException.cs
+++ b/Misaki.HighPerformance.LowLevel/contentFiles/cs/any/MemoryLeakException.cs
@@ -1,5 +1,6 @@
using Misaki.HighPerformance.LowLevel.Buffer;
using System.Diagnostics;
+using System.Runtime.CompilerServices;
using System.Text;
namespace Misaki.HighPerformance.LowLevel;
@@ -45,9 +46,11 @@ public class MemoryLeakException : Exception
for (var i = 0; i < stackTrace.FrameCount; i++)
{
var frame = stackTrace.GetFrame(i);
- if (frame != null)
+ var fileName = frame?.GetFileName();
+
+ if (frame != null && fileName != null)
{
- stringBuilder.AppendLine($"File: {frame.GetFileName()}, Method: {DiagnosticMethodInfo.Create(frame)?.Name}, Line: {frame.GetFileLineNumber()}");
+ stringBuilder.AppendLine($"File: {fileName}, Method: {DiagnosticMethodInfo.Create(frame)?.Name}, Line: {frame.GetFileLineNumber()}");
}
}
diff --git a/Misaki.HighPerformance.Mathematics.SPMD/IJobSPMD.cs b/Misaki.HighPerformance.Mathematics.SPMD/IJobSPMD.cs
index 5be7f99..1527122 100644
--- a/Misaki.HighPerformance.Mathematics.SPMD/IJobSPMD.cs
+++ b/Misaki.HighPerformance.Mathematics.SPMD/IJobSPMD.cs
@@ -34,27 +34,6 @@ internal struct SPMDJobWrapper : IJobParallelFor
}
}
}
-
- //public void Execute(int startIndex, int endIndex, int threadIndex)
- //{
- // for (int i = startIndex; i < endIndex; i++)
- // {
- // var baseIndex = i * WideLane.LaneWidth;
- // var remaining = totalCount - baseIndex;
-
- // if (remaining >= WideLane.LaneWidth)
- // {
- // innerJob.Execute>(baseIndex, threadIndex);
- // }
- // else
- // {
- // for (var j = 0; j < remaining; j++)
- // {
- // innerJob.Execute>(baseIndex + j, threadIndex);
- // }
- // }
- // }
- //}
}
internal struct SPMDScalerJobWrapper : IJobParallelFor
@@ -68,15 +47,6 @@ internal struct SPMDScalerJobWrapper : IJobParallelFor
{
innerJob.Execute>(loopIndex, threadIndex);
}
-
- //[MethodImpl(MethodImplOptions.AggressiveInlining)]
- //public void Execute(int startIndex, int endIndex, int threadIndex)
- //{
- // for (int i = startIndex; i < endIndex; i++)
- // {
- // innerJob.Execute>(i, threadIndex);
- // }
- //}
}
public static class IJobParallelForSPMDExtensions