feat(core): add scalar ops and improve memory handling
Added scalar operator overloads for Vector types, fixed pointer math in Store methods, and improved enumerator and memory management. Updated test setup and removed allocation leak tests. - Added left-hand scalar operator overloads for Vector2/3/4. - Fixed pointer arithmetic in Store and GetUnsafePtr methods. - Marked SetValue as readonly in UnsafeSparseSet. - Improved enumerator initialization/reset for slot map and sparse set. - Updated test projects' AssemblyVersion. - Removed TestAllocationManager and added global AllocationManager setup/teardown. - Updated TestConcurrentSlotMap for thread safety and correct cancellation. - Minor formatting and parameter improvements.
This commit is contained in:
@@ -54,7 +54,7 @@ public unsafe struct UnsafeSlotMap<T> : IUnsafeCollection<T>
|
|||||||
public Enumerator(UnsafeSlotMap<T>* collection)
|
public Enumerator(UnsafeSlotMap<T>* collection)
|
||||||
{
|
{
|
||||||
_collection = collection;
|
_collection = collection;
|
||||||
_currentIndex = 0;
|
_currentIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MoveNext()
|
public bool MoveNext()
|
||||||
@@ -65,7 +65,7 @@ public unsafe struct UnsafeSlotMap<T> : IUnsafeCollection<T>
|
|||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
_currentIndex = 0;
|
_currentIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public unsafe struct UnsafeSparseSet<T> : IUnsafeCollection<T>
|
|||||||
public Enumerator(UnsafeSparseSet<T>* collection)
|
public Enumerator(UnsafeSparseSet<T>* collection)
|
||||||
{
|
{
|
||||||
_collection = collection;
|
_collection = collection;
|
||||||
_currentIndex = 0;
|
_currentIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MoveNext()
|
public bool MoveNext()
|
||||||
@@ -67,7 +67,7 @@ public unsafe struct UnsafeSparseSet<T> : IUnsafeCollection<T>
|
|||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
_currentIndex = 0;
|
_currentIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly void Dispose()
|
public readonly void Dispose()
|
||||||
@@ -364,7 +364,7 @@ public unsafe struct UnsafeSparseSet<T> : IUnsafeCollection<T>
|
|||||||
/// <param name="generation">The Generation number to validate against the stored Generation.</param>
|
/// <param name="generation">The Generation number to validate against the stored Generation.</param>
|
||||||
/// <param name="value">The new value.</param>
|
/// <param name="value">The new value.</param>
|
||||||
/// <returns>True if the value was updated, false if the sparse index was not found.</returns>
|
/// <returns>True if the value was updated, false if the sparse index was not found.</returns>
|
||||||
public bool SetValue(int sparseIndex, int generation, T value)
|
public readonly bool SetValue(int sparseIndex, int generation, T value)
|
||||||
{
|
{
|
||||||
if (!Contains(sparseIndex, generation))
|
if (!Contains(sparseIndex, generation))
|
||||||
{
|
{
|
||||||
@@ -422,7 +422,7 @@ public unsafe struct UnsafeSparseSet<T> : IUnsafeCollection<T>
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly void* GetUnsafePtr()
|
public readonly void* GetUnsafePtr()
|
||||||
{
|
{
|
||||||
return (T*)_dense.GetUnsafePtr() + 1;
|
return (T*)_dense.GetUnsafePtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Authors>Misaki</Authors>
|
<Authors>Misaki</Authors>
|
||||||
<AssemblyVersion>1.6.7</AssemblyVersion>
|
<AssemblyVersion>1.6.8</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>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<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>
|
||||||
|
|||||||
@@ -83,14 +83,14 @@ public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Store(TNumber* px, TNumber* py)
|
public void Store(TNumber* px, TNumber* py)
|
||||||
{
|
{
|
||||||
x.Store(px);
|
x.Store(px);
|
||||||
y.Store(py);
|
y.Store(py);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Store(ref TNumber x, ref TNumber y)
|
public void Store(ref TNumber x, ref TNumber y)
|
||||||
{
|
{
|
||||||
this.x.Store(ref x);
|
this.x.Store(ref x);
|
||||||
this.y.Store(ref y);
|
this.y.Store(ref y);
|
||||||
@@ -145,7 +145,7 @@ public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber
|
|||||||
y = vector.y - lane,
|
y = vector.y - lane,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector2<TLane, TNumber> operator -(TLane lane, in Vector2<TLane, TNumber> vector)
|
public static Vector2<TLane, TNumber> operator -(TLane lane, in Vector2<TLane, TNumber> vector)
|
||||||
{
|
{
|
||||||
@@ -175,7 +175,7 @@ public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber
|
|||||||
y = vector.y * lane,
|
y = vector.y * lane,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector2<TLane, TNumber> operator *(TLane lane, in Vector2<TLane, TNumber> vector)
|
public static Vector2<TLane, TNumber> operator *(TLane lane, in Vector2<TLane, TNumber> vector)
|
||||||
{
|
{
|
||||||
@@ -195,7 +195,7 @@ public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber
|
|||||||
y = left.y / right.y,
|
y = left.y / right.y,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector2<TLane, TNumber> operator /(in Vector2<TLane, TNumber> vector, TLane lane)
|
public static Vector2<TLane, TNumber> operator /(in Vector2<TLane, TNumber> vector, TLane lane)
|
||||||
{
|
{
|
||||||
@@ -205,7 +205,7 @@ public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber
|
|||||||
y = vector.y / lane,
|
y = vector.y / lane,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector2<TLane, TNumber> operator /(TLane lane, in Vector2<TLane, TNumber> vector)
|
public static Vector2<TLane, TNumber> operator /(TLane lane, in Vector2<TLane, TNumber> vector)
|
||||||
{
|
{
|
||||||
@@ -226,7 +226,7 @@ public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector2<TLane, TNumber> operator ==(in Vector2<TLane, TNumber> vector, TLane lane)
|
public static Vector2<TLane, TNumber> operator ==(in Vector2<TLane, TNumber> vector, TLane lane)
|
||||||
{
|
{
|
||||||
@@ -236,7 +236,7 @@ public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber
|
|||||||
y = vector.y == lane,
|
y = vector.y == lane,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector2<TLane, TNumber> operator ==(TLane lane, in Vector2<TLane, TNumber> vector)
|
public static Vector2<TLane, TNumber> operator ==(TLane lane, in Vector2<TLane, TNumber> vector)
|
||||||
{
|
{
|
||||||
@@ -276,7 +276,7 @@ public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber
|
|||||||
y = lane != vector.y,
|
y = lane != vector.y,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector2<TLane, TNumber> operator >(in Vector2<TLane, TNumber> left, in Vector2<TLane, TNumber> right)
|
public static Vector2<TLane, TNumber> operator >(in Vector2<TLane, TNumber> left, in Vector2<TLane, TNumber> right)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -76,9 +76,9 @@ public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber
|
|||||||
|
|
||||||
for (var i = 0; i < width; i++)
|
for (var i = 0; i < width; i++)
|
||||||
{
|
{
|
||||||
pDst[i * 2 + 0] = x[i];
|
pDst[i * 3 + 0] = x[i];
|
||||||
pDst[i * 2 + 1] = y[i];
|
pDst[i * 3 + 1] = y[i];
|
||||||
pDst[i * 2 + 2] = z[i];
|
pDst[i * 3 + 2] = z[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Store(TNumber* px, TNumber* py, TNumber* pz)
|
public void Store(TNumber* px, TNumber* py, TNumber* pz)
|
||||||
{
|
{
|
||||||
x.Store(px);
|
x.Store(px);
|
||||||
y.Store(py);
|
y.Store(py);
|
||||||
@@ -97,7 +97,7 @@ public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Store(ref TNumber x, ref TNumber y, ref TNumber z)
|
public void Store(ref TNumber x, ref TNumber y, ref TNumber z)
|
||||||
{
|
{
|
||||||
this.x.Store(ref x);
|
this.x.Store(ref x);
|
||||||
this.y.Store(ref y);
|
this.y.Store(ref y);
|
||||||
@@ -158,7 +158,7 @@ public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber
|
|||||||
z = vector.z - lane,
|
z = vector.z - lane,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector3<TLane, TNumber> operator -(TLane lane, in Vector3<TLane, TNumber> vector)
|
public static Vector3<TLane, TNumber> operator -(TLane lane, in Vector3<TLane, TNumber> vector)
|
||||||
{
|
{
|
||||||
@@ -191,7 +191,7 @@ public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber
|
|||||||
z = vector.z * lane,
|
z = vector.z * lane,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector3<TLane, TNumber> operator *(TLane lane, in Vector3<TLane, TNumber> vector)
|
public static Vector3<TLane, TNumber> operator *(TLane lane, in Vector3<TLane, TNumber> vector)
|
||||||
{
|
{
|
||||||
@@ -213,7 +213,7 @@ public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber
|
|||||||
z = left.z / right.z,
|
z = left.z / right.z,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector3<TLane, TNumber> operator /(in Vector3<TLane, TNumber> vector, TLane lane)
|
public static Vector3<TLane, TNumber> operator /(in Vector3<TLane, TNumber> vector, TLane lane)
|
||||||
{
|
{
|
||||||
@@ -224,7 +224,7 @@ public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber
|
|||||||
z = vector.z / lane,
|
z = vector.z / lane,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector3<TLane, TNumber> operator /(TLane lane, in Vector3<TLane, TNumber> vector)
|
public static Vector3<TLane, TNumber> operator /(TLane lane, in Vector3<TLane, TNumber> vector)
|
||||||
{
|
{
|
||||||
@@ -247,7 +247,7 @@ public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector3<TLane, TNumber> operator ==(in Vector3<TLane, TNumber> vector, TLane lane)
|
public static Vector3<TLane, TNumber> operator ==(in Vector3<TLane, TNumber> vector, TLane lane)
|
||||||
{
|
{
|
||||||
@@ -258,7 +258,7 @@ public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber
|
|||||||
z = vector.z == lane,
|
z = vector.z == lane,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector3<TLane, TNumber> operator ==(TLane lane, in Vector3<TLane, TNumber> vector)
|
public static Vector3<TLane, TNumber> operator ==(TLane lane, in Vector3<TLane, TNumber> vector)
|
||||||
{
|
{
|
||||||
@@ -302,7 +302,7 @@ public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber
|
|||||||
z = lane != vector.z,
|
z = lane != vector.z,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector3<TLane, TNumber> operator >(in Vector3<TLane, TNumber> left, in Vector3<TLane, TNumber> right)
|
public static Vector3<TLane, TNumber> operator >(in Vector3<TLane, TNumber> left, in Vector3<TLane, TNumber> right)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -81,10 +81,10 @@ public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber
|
|||||||
|
|
||||||
for (var i = 0; i < width; i++)
|
for (var i = 0; i < width; i++)
|
||||||
{
|
{
|
||||||
pDst[i * 2 + 0] = x[i];
|
pDst[i * 4 + 0] = x[i];
|
||||||
pDst[i * 2 + 1] = y[i];
|
pDst[i * 4 + 1] = y[i];
|
||||||
pDst[i * 2 + 2] = z[i];
|
pDst[i * 4 + 2] = z[i];
|
||||||
pDst[i * 2 + 3] = w[i];
|
pDst[i * 4 + 3] = w[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Store(TNumber* px, TNumber* py, TNumber* pz, TNumber* pw)
|
public void Store(TNumber* px, TNumber* py, TNumber* pz, TNumber* pw)
|
||||||
{
|
{
|
||||||
x.Store(px);
|
x.Store(px);
|
||||||
y.Store(py);
|
y.Store(py);
|
||||||
@@ -104,7 +104,7 @@ public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Store(ref TNumber x, ref TNumber y, ref TNumber z, ref TNumber w)
|
public void Store(ref TNumber x, ref TNumber y, ref TNumber z, ref TNumber w)
|
||||||
{
|
{
|
||||||
this.x.Store(ref x);
|
this.x.Store(ref x);
|
||||||
this.y.Store(ref y);
|
this.y.Store(ref y);
|
||||||
@@ -171,7 +171,7 @@ public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber
|
|||||||
w = vector.w - lane,
|
w = vector.w - lane,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector4<TLane, TNumber> operator -(TLane lane, in Vector4<TLane, TNumber> vector)
|
public static Vector4<TLane, TNumber> operator -(TLane lane, in Vector4<TLane, TNumber> vector)
|
||||||
{
|
{
|
||||||
@@ -207,7 +207,7 @@ public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber
|
|||||||
w = vector.w * lane,
|
w = vector.w * lane,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector4<TLane, TNumber> operator *(TLane lane, in Vector4<TLane, TNumber> vector)
|
public static Vector4<TLane, TNumber> operator *(TLane lane, in Vector4<TLane, TNumber> vector)
|
||||||
{
|
{
|
||||||
@@ -231,7 +231,7 @@ public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber
|
|||||||
w = left.w / right.w,
|
w = left.w / right.w,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector4<TLane, TNumber> operator /(in Vector4<TLane, TNumber> vector, TLane lane)
|
public static Vector4<TLane, TNumber> operator /(in Vector4<TLane, TNumber> vector, TLane lane)
|
||||||
{
|
{
|
||||||
@@ -243,7 +243,7 @@ public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber
|
|||||||
w = vector.w / lane,
|
w = vector.w / lane,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector4<TLane, TNumber> operator /(TLane lane, in Vector4<TLane, TNumber> vector)
|
public static Vector4<TLane, TNumber> operator /(TLane lane, in Vector4<TLane, TNumber> vector)
|
||||||
{
|
{
|
||||||
@@ -268,7 +268,7 @@ public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector4<TLane, TNumber> operator ==(in Vector4<TLane, TNumber> vector, TLane lane)
|
public static Vector4<TLane, TNumber> operator ==(in Vector4<TLane, TNumber> vector, TLane lane)
|
||||||
{
|
{
|
||||||
@@ -280,7 +280,7 @@ public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber
|
|||||||
w = vector.w == lane,
|
w = vector.w == lane,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector4<TLane, TNumber> operator ==(TLane lane, in Vector4<TLane, TNumber> vector)
|
public static Vector4<TLane, TNumber> operator ==(TLane lane, in Vector4<TLane, TNumber> vector)
|
||||||
{
|
{
|
||||||
@@ -328,7 +328,7 @@ public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber
|
|||||||
w = lane != vector.w,
|
w = lane != vector.w,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector4<TLane, TNumber> operator >(in Vector4<TLane, TNumber> left, in Vector4<TLane, TNumber> right)
|
public static Vector4<TLane, TNumber> operator >(in Vector4<TLane, TNumber> left, in Vector4<TLane, TNumber> right)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ public unsafe struct {typeName} : IEquatable<{typeName}>
|
|||||||
|
|
||||||
for (var i = 0; i < width; i++)
|
for (var i = 0; i < width; i++)
|
||||||
{{
|
{{
|
||||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"pDst[i * 2 + {dim}] = {components[dim]}[i];"))}
|
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"pDst[i * {dimension} + {dim}] = {components[dim]}[i];"))}
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|||||||
@@ -39,4 +39,4 @@ UnsafeArray<int> Test2(ref readonly MemoryPool<VirtualStack, VirtualStack.Creati
|
|||||||
using var arr = new UnsafeArray<int>(1000, pool.AllocationHandle);
|
using var arr = new UnsafeArray<int>(1000, pool.AllocationHandle);
|
||||||
var arr1 = new UnsafeArray<int>(1000, pool.AllocationHandle);
|
var arr1 = new UnsafeArray<int>(1000, pool.AllocationHandle);
|
||||||
return arr1;
|
return arr1;
|
||||||
}
|
}
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
using Misaki.HighPerformance.LowLevel;
|
|
||||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
|
||||||
using Misaki.HighPerformance.LowLevel.Collections;
|
|
||||||
|
|
||||||
namespace Misaki.HighPerformance.Test.UnitTest.Buffer;
|
|
||||||
|
|
||||||
[TestClass]
|
|
||||||
public class TestAllocationManager
|
|
||||||
{
|
|
||||||
[TestMethod]
|
|
||||||
public void ShouldNotLeakTest()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var array = new UnsafeArray<int>(10, Allocator.Persistent);
|
|
||||||
var array2 = new UnsafeArray<int>(10, Allocator.Persistent);
|
|
||||||
|
|
||||||
array.Dispose();
|
|
||||||
array2.Dispose();
|
|
||||||
|
|
||||||
AllocationManager.Dispose();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
#if MHP_ENABLE_SAFETY_CHECKS
|
|
||||||
var leaks = AllocationManager.LiveAllocationCount;
|
|
||||||
Assert.AreEqual(0, leaks);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ShouldLeakTest()
|
|
||||||
{
|
|
||||||
var array = new UnsafeArray<int>(10, Allocator.Persistent);
|
|
||||||
var array2 = new UnsafeArray<int>(10, Allocator.Persistent);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
AllocationManager.Dispose();
|
|
||||||
}
|
|
||||||
catch (MemoryLeakException)
|
|
||||||
{
|
|
||||||
#if MHP_ENABLE_SAFETY_CHECKS
|
|
||||||
var leaks = AllocationManager.LiveAllocationCount;
|
|
||||||
Assert.AreEqual(2, leaks);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
array.Dispose();
|
|
||||||
array2.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if ENABLE_SAFETY_CHECKS
|
|
||||||
Assert.Fail("Expected MemoryLeakException was not thrown.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,7 @@ using System.Collections.Concurrent;
|
|||||||
namespace Misaki.HighPerformance.Test.UnitTest.Collections;
|
namespace Misaki.HighPerformance.Test.UnitTest.Collections;
|
||||||
|
|
||||||
[TestClass]
|
[TestClass]
|
||||||
|
[DoNotParallelize]
|
||||||
public class TestConcurrentSlotMap
|
public class TestConcurrentSlotMap
|
||||||
{
|
{
|
||||||
private ConcurrentSlotMap<int> _slotMap = null!;
|
private ConcurrentSlotMap<int> _slotMap = null!;
|
||||||
@@ -79,10 +80,10 @@ public class TestConcurrentSlotMap
|
|||||||
{
|
{
|
||||||
_slotMap.Add(i, out _);
|
_slotMap.Add(i, out _);
|
||||||
}
|
}
|
||||||
}, TestContext.CancellationTokenSource.Token));
|
}, TestContext.CancellationToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
Task.WaitAll(tasks, TestContext.CancellationTokenSource.Token);
|
Task.WaitAll(tasks, TestContext.CancellationToken);
|
||||||
Assert.AreEqual(threadCount * itemsPerThread, _slotMap.Count);
|
Assert.AreEqual(threadCount * itemsPerThread, _slotMap.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +94,6 @@ public class TestConcurrentSlotMap
|
|||||||
const int operationsPerThread = 1000;
|
const int operationsPerThread = 1000;
|
||||||
|
|
||||||
var tasks = new List<Task>();
|
var tasks = new List<Task>();
|
||||||
var rand = new Random();
|
|
||||||
var addedItems = new ConcurrentBag<(int slotIndex, int generation)>();
|
var addedItems = new ConcurrentBag<(int slotIndex, int generation)>();
|
||||||
|
|
||||||
var count = 0;
|
var count = 0;
|
||||||
@@ -104,7 +104,7 @@ public class TestConcurrentSlotMap
|
|||||||
{
|
{
|
||||||
for (var i = 0; i < operationsPerThread; i++)
|
for (var i = 0; i < operationsPerThread; i++)
|
||||||
{
|
{
|
||||||
if (rand.NextDouble() < 0.5)
|
if (Random.Shared.NextDouble() < 0.5)
|
||||||
{
|
{
|
||||||
var slotIndex = _slotMap.Add(i, out var generation);
|
var slotIndex = _slotMap.Add(i, out var generation);
|
||||||
addedItems.Add((slotIndex, generation));
|
addedItems.Add((slotIndex, generation));
|
||||||
@@ -113,14 +113,16 @@ public class TestConcurrentSlotMap
|
|||||||
}
|
}
|
||||||
else if (addedItems.TryTake(out var item))
|
else if (addedItems.TryTake(out var item))
|
||||||
{
|
{
|
||||||
_slotMap.Remove(item.slotIndex, item.generation);
|
if (_slotMap.Remove(item.slotIndex, item.generation))
|
||||||
Interlocked.Decrement(ref count);
|
{
|
||||||
|
Interlocked.Decrement(ref count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, TestContext.CancellationTokenSource.Token));
|
}, TestContext.CancellationToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
Task.WaitAll(tasks, TestContext.CancellationTokenSource.Token);
|
Task.WaitAll(tasks, TestContext.CancellationToken);
|
||||||
|
|
||||||
Assert.AreEqual(count, _slotMap.Count);
|
Assert.AreEqual(count, _slotMap.Count);
|
||||||
}
|
}
|
||||||
|
|||||||
19
Misaki.HighPerformance.Test/UnitTest/GlobalSetup.cs
Normal file
19
Misaki.HighPerformance.Test/UnitTest/GlobalSetup.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
|
|
||||||
|
namespace Misaki.HighPerformance.Test.UnitTest;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public static class GlobalSetup
|
||||||
|
{
|
||||||
|
[GlobalTestInitialize]
|
||||||
|
public static void GlobalInitialize(TestContext ctx)
|
||||||
|
{
|
||||||
|
AllocationManager.Initialize(AllocationManagerInitOpts.Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
[GlobalTestCleanup]
|
||||||
|
public static void GlobalCleanup(TestContext ctx)
|
||||||
|
{
|
||||||
|
AllocationManager.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user