This commit is contained in:
DCFApixels 2024-11-19 18:43:21 +08:00
parent d3f74dd456
commit c9f7826a67
4 changed files with 45 additions and 81 deletions

View File

@ -296,7 +296,7 @@ namespace DCFApixels.DragonECS
public void OnWorldDestroy() { } public void OnWorldDestroy() { }
public void OnWorldResize(int startWorldNewSize) public void OnWorldResize(int startWorldNewSize)
{ {
IntHashes.InitFor(startWorldNewSize); IntHash.InitFor(startWorldNewSize);
} }
#endregion #endregion
} }

View File

@ -58,13 +58,11 @@ namespace DCFApixels.DragonECS.Graphs.Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T* New<T>(int capacity) where T : unmanaged public static T* New<T>(int capacity) where T : unmanaged
{ {
//return (T*)Marshal.AllocHGlobal(Marshal.SizeOf<T>() * capacity).ToPointer();
return (T*)Marshal.AllocHGlobal(MetaCache<T>.Size * capacity).ToPointer(); return (T*)Marshal.AllocHGlobal(MetaCache<T>.Size * capacity).ToPointer();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void New<T>(out T* ptr, int capacity) where T : unmanaged public static void New<T>(out T* ptr, int capacity) where T : unmanaged
{ {
//ptr = (T*)Marshal.AllocHGlobal(Marshal.SizeOf<T>() * capacity).ToPointer();
ptr = (T*)Marshal.AllocHGlobal(MetaCache<T>.Size * capacity).ToPointer(); ptr = (T*)Marshal.AllocHGlobal(MetaCache<T>.Size * capacity).ToPointer();
} }

35
src/Internal/IntHashes.cs Normal file
View File

@ -0,0 +1,35 @@
namespace DCFApixels.DragonECS.Graphs.Internal
{
internal static unsafe class IntHash
{
public static int* hashes = null;
public static int length = 0;
public static void InitFor(int count)
{
if (count <= length) { return; }
unchecked
{
//quasi random consts
const decimal G1 = 1.6180339887498948482045868383m;
const uint Q32_MAX = uint.MaxValue;
const uint X1_Q32 = (uint)(1m / G1 * Q32_MAX) + 1;
if (hashes != null)
{
UnmanagedArrayUtility.Free(hashes);
}
hashes = UnmanagedArrayUtility.New<int>(count);
uint state = 3571U;
for (int i = 0; i < count; i++)
{
state = X1_Q32 * state;
hashes[i] = ((int)state) & 0x7FFFFFFF;
}
count = length;
}
}
}
}

View File

@ -4,12 +4,12 @@ using TValue = System.Int32;
namespace DCFApixels.DragonECS.Graphs.Internal namespace DCFApixels.DragonECS.Graphs.Internal
{ {
public sealed unsafe class SparseMatrix internal sealed unsafe class SparseMatrix
{ {
private const int _NULL_NEXT = -1; private const int _NULL_NEXT = -1;
public const int MIN_CAPACITY_BITS_OFFSET = 4; private const int MIN_CAPACITY_BITS_OFFSET = 4;
public const int MIN_CAPACITY = 1 << MIN_CAPACITY_BITS_OFFSET; private const int MIN_CAPACITY = 1 << MIN_CAPACITY_BITS_OFFSET;
private const int CHAIN_LENGTH_THRESHOLD = 5; private const int CHAIN_LENGTH_THRESHOLD = 5;
private const float CHAIN_LENGTH_THRESHOLD_CAPCITY_THRESHOLD = 0.65f; private const float CHAIN_LENGTH_THRESHOLD_CAPCITY_THRESHOLD = 0.65f;
@ -78,42 +78,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal
Throw.ArgumentException("Has(x, y) is true"); Throw.ArgumentException("Has(x, y) is true");
} }
#endif #endif
int hash = IntHashes.hashes[y] ^ x; int hash = IntHash.hashes[y] ^ x;
AddInternal(key, hash, value);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryAdd(int x, int y, TValue value)
{
unchecked
{
long key = KeyUtility.FromXY(x, y);
int hash = IntHashes.hashes[y] ^ x;
if (FindEntry(x, y) >= 0)
{
return false;
}
AddInternal(key, hash, value);
return true;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Set(int x, int y, TValue value)
{
unchecked
{
long key = KeyUtility.FromXY(x, y);
int hash = IntHashes.hashes[y] ^ x;
int targetBucket = hash & _modBitMask;
for (int i = _buckets[targetBucket]; i != _NULL_NEXT; i = _entries[i].next)
{
if (_entries[i].hash == hash && _entries[i].key == key)
{
_entries[i].value = value;
return;
}
}
AddInternal(key, hash, value); AddInternal(key, hash, value);
} }
} }
@ -163,7 +128,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal
private int FindEntry(int x, int y) private int FindEntry(int x, int y)
{ {
long key = KeyUtility.FromXY(x, y); long key = KeyUtility.FromXY(x, y);
int hash = IntHashes.hashes[y] ^ x; int hash = IntHash.hashes[y] ^ x;
for (int i = _buckets[hash & _modBitMask]; i != _NULL_NEXT; i = _entries[i].next) for (int i = _buckets[hash & _modBitMask]; i != _NULL_NEXT; i = _entries[i].next)
{ {
if (_entries[i].hash == hash && _entries[i].key == key) if (_entries[i].hash == hash && _entries[i].key == key)
@ -209,7 +174,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal
public bool TryDel(int x, int y) public bool TryDel(int x, int y)
{ {
long key = KeyUtility.FromXY(x, y); long key = KeyUtility.FromXY(x, y);
int hash = IntHashes.hashes[y] ^ x; int hash = IntHash.hashes[y] ^ x;
int targetBucket = hash & _modBitMask; int targetBucket = hash & _modBitMask;
ref int bucket = ref _buckets[targetBucket]; ref int bucket = ref _buckets[targetBucket];
@ -291,6 +256,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal
SetCapacity(newSize); SetCapacity(newSize);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SetCapacity(int newSize) private void SetCapacity(int newSize)
{ {
_capacity = newSize; _capacity = newSize;
@ -300,9 +266,8 @@ namespace DCFApixels.DragonECS.Graphs.Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int NormalizeCapacity(int capacity) private static int NormalizeCapacity(int capacity)
{ {
int result = MIN_CAPACITY; int result = ArrayUtility.NormalizeSizeToPowerOfTwo(capacity);
while (result < capacity) { result <<= 1; } return result < MIN_CAPACITY ? MIN_CAPACITY : result;
return result;
} }
#endregion #endregion
@ -330,38 +295,4 @@ namespace DCFApixels.DragonECS.Graphs.Internal
} }
#endregion #endregion
} }
public static unsafe class IntHashes
{
public static int* hashes = null;
public static int length = 0;
public static void InitFor(int count)
{
if (count <= length) { return; }
unchecked
{
//quasi random consts
const decimal G1 = 1.6180339887498948482045868383m;
const uint Q32_MAX = uint.MaxValue;
const uint X1_Q32 = (uint)(1m / G1 * Q32_MAX) + 1;
if (hashes != null)
{
UnmanagedArrayUtility.Free(hashes);
}
hashes = UnmanagedArrayUtility.New<int>(count);
uint state = 3571U;
for (int i = 0; i < count; i++)
{
state = X1_Q32 * state;
hashes[i] = ((int)state) & 0x7FFFFFFF;
}
count = length;
}
}
}
} }