This commit is contained in:
DCFApixels 2024-11-19 17:03:15 +08:00
parent b728206d8b
commit d3f74dd456
4 changed files with 53 additions and 145 deletions

View File

@ -147,20 +147,20 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region MoveRelation #region MoveRelation
[MethodImpl(MethodImplOptions.AggressiveInlining)] //[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void MoveRelation(int relEntityID, int newStartEntityID, int newEndEntityID) //private void MoveRelation(int relEntityID, int newStartEntityID, int newEndEntityID)
{ //{
var startEnd = GetRelationStartEnd(relEntityID); // var startEnd = GetRelationStartEnd(relEntityID);
//
//Тут будет не стабильное состояние если TryDel пройдет, а TryAdd - нет // //Тут будет не стабильное состояние если TryDel пройдет, а TryAdd - нет
if (_matrix.TryDel(startEnd.start, startEnd.end) == false || // if (_matrix.TryDel(startEnd.start, startEnd.end) == false ||
_matrix.TryAdd(newStartEntityID, newEndEntityID, relEntityID) == false) // _matrix.TryAdd(newStartEntityID, newEndEntityID, relEntityID) == false)
{ // {
Throw.UndefinedException(); // Throw.UndefinedException();
} // }
//
_relEntityInfos[relEntityID] = new RelationInfo(newStartEntityID, newEndEntityID); // _relEntityInfos[relEntityID] = new RelationInfo(newStartEntityID, newEndEntityID);
} //}
#endregion #endregion
#region Get #region Get

View File

@ -4,8 +4,8 @@ using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS.Graphs.Internal namespace DCFApixels.DragonECS.Graphs.Internal
{ {
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)]
[Serializable] [Serializable]
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)]
internal readonly struct RelationInfo : IEquatable<RelationInfo> internal readonly struct RelationInfo : IEquatable<RelationInfo>
{ {
public static readonly RelationInfo Empty = new RelationInfo(); public static readonly RelationInfo Empty = new RelationInfo();

View File

@ -1,6 +1,4 @@
using System; using System.Runtime.CompilerServices;
using System.Data.SqlTypes;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using TValue = System.Int32; using TValue = System.Int32;
@ -8,6 +6,8 @@ namespace DCFApixels.DragonECS.Graphs.Internal
{ {
public sealed unsafe class SparseMatrix public sealed unsafe class SparseMatrix
{ {
private const int _NULL_NEXT = -1;
public const int MIN_CAPACITY_BITS_OFFSET = 4; public const int MIN_CAPACITY_BITS_OFFSET = 4;
public const int MIN_CAPACITY = 1 << MIN_CAPACITY_BITS_OFFSET; public const int MIN_CAPACITY = 1 << MIN_CAPACITY_BITS_OFFSET;
@ -48,7 +48,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal
_entries = UnmanagedArrayUtility.NewAndInit<Entry>(minCapacity); _entries = UnmanagedArrayUtility.NewAndInit<Entry>(minCapacity);
for (int i = 0; i < minCapacity; i++) for (int i = 0; i < minCapacity; i++)
{ {
_buckets[i] = -1; _buckets[i] = _NULL_NEXT;
} }
_modBitMask = (minCapacity - 1) & 0x7FFFFFFF; _modBitMask = (minCapacity - 1) & 0x7FFFFFFF;
@ -106,7 +106,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal
int hash = IntHashes.hashes[y] ^ x; int hash = IntHashes.hashes[y] ^ x;
int targetBucket = hash & _modBitMask; int targetBucket = hash & _modBitMask;
for (int i = _buckets[targetBucket]; i >= 0; i = _entries[i].next) for (int i = _buckets[targetBucket]; 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)
{ {
@ -146,14 +146,14 @@ namespace DCFApixels.DragonECS.Graphs.Internal
if (_freeCount < 0) { Throw.UndefinedException(); } if (_freeCount < 0) { Throw.UndefinedException(); }
#endif #endif
ref int basket = ref _buckets[targetBucket]; ref int bucket = ref _buckets[targetBucket];
ref Entry entry = ref _entries[index]; ref Entry entry = ref _entries[index];
entry.hash = hash; entry.hash = hash;
entry.next = basket; entry.next = bucket;
entry.key = key; entry.key = key;
entry.value = value; entry.value = value;
basket = index; bucket = index;
} }
} }
#endregion #endregion
@ -164,7 +164,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal
{ {
long key = KeyUtility.FromXY(x, y); long key = KeyUtility.FromXY(x, y);
int hash = IntHashes.hashes[y] ^ x; int hash = IntHashes.hashes[y] ^ x;
for (int i = _buckets[hash & _modBitMask]; i >= 0; 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)
{ {
@ -211,24 +211,25 @@ namespace DCFApixels.DragonECS.Graphs.Internal
long key = KeyUtility.FromXY(x, y); long key = KeyUtility.FromXY(x, y);
int hash = IntHashes.hashes[y] ^ x; int hash = IntHashes.hashes[y] ^ x;
int targetBucket = hash & _modBitMask; int targetBucket = hash & _modBitMask;
ref int basket = ref _buckets[targetBucket]; ref int bucket = ref _buckets[targetBucket];
int last = -1; int last = -1;
for (int i = basket; i >= 0; last = i, i = _entries[i].next) for (int i = bucket; i >= 0; last = i, i = _entries[i].next)
{ {
if (_entries[i].hash == hash && _entries[i].key == key) if (_entries[i].hash == hash && _entries[i].key == key)
{ {
if (last < 0) if (last < 0)
{ {
basket = _entries[i].next; bucket = _entries[i].next;
} }
else else
{ {
_entries[last].next = _entries[i].next; _entries[last].next = _entries[i].next;
} }
_entries[i].hash = -1;
_entries[i].next = _freeList; _entries[i].next = _freeList;
_entries[i].key = default; //Key.Null; //_entries[i].key = default;
_entries[i].value = default; //_entries[i].value = default;
_freeList = i; _freeList = i;
_freeCount++; _freeCount++;
return true; return true;
@ -245,7 +246,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal
{ {
for (int i = 0; i < _capacity; i++) for (int i = 0; i < _capacity; i++)
{ {
_buckets[i] = -1; _buckets[i] = _NULL_NEXT;
} }
for (int i = 0; i < _capacity; i++) for (int i = 0; i < _capacity; i++)
{ {
@ -261,14 +262,13 @@ namespace DCFApixels.DragonECS.Graphs.Internal
private void Resize() private void Resize()
{ {
int newSize = _capacity << 1; int newSize = _capacity << 1;
Console.WriteLine($"Resize {newSize}");
_modBitMask = (newSize - 1) & 0x7FFFFFFF; _modBitMask = (newSize - 1) & 0x7FFFFFFF;
//newBuckets create and ini //newBuckets create and ini
int* newBuckets = UnmanagedArrayUtility.New<int>(newSize); int* newBuckets = UnmanagedArrayUtility.New<int>(newSize);
for (int i = 0; i < newSize; i++) for (int i = 0; i < newSize; i++)
{ {
newBuckets[i] = -1; newBuckets[i] = _NULL_NEXT;
} }
//END newBuckets create and ini //END newBuckets create and ini
@ -278,9 +278,9 @@ namespace DCFApixels.DragonECS.Graphs.Internal
if (newEntries[i].key >= 0) if (newEntries[i].key >= 0)
{ {
ref Entry entry = ref newEntries[i]; ref Entry entry = ref newEntries[i];
ref int basket = ref newBuckets[entry.hash & _modBitMask]; ref int bucket = ref newBuckets[entry.hash & _modBitMask];
entry.next = basket; entry.next = bucket;
basket = i; bucket = i;
} }
} }
@ -310,8 +310,8 @@ namespace DCFApixels.DragonECS.Graphs.Internal
[StructLayout(LayoutKind.Sequential, Pack = 4)] [StructLayout(LayoutKind.Sequential, Pack = 4)]
private struct Entry private struct Entry
{ {
public int next; // Index of next entry, -1 if last
public long key; public long key;
public int next; // Index of next entry, -1 if last
public int hash; public int hash;
public TValue value; public TValue value;
public override string ToString() { return key == 0 ? "NULL" : $"{key} {value}"; } public override string ToString() { return key == 0 ? "NULL" : $"{key} {value}"; }
@ -327,21 +327,6 @@ namespace DCFApixels.DragonECS.Graphs.Internal
return ((long)x << 32) | (long)y; return ((long)x << 32) | (long)y;
} }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int Mixing(int v)
{
unchecked
{
int i = v;
v *= 3571;
v ^= v << 13;
v ^= v >> 17;
v ^= v << 5;
//v = (v >> 28) + v ^ i;
return v;
}
}
} }
#endregion #endregion
} }
@ -353,107 +338,30 @@ namespace DCFApixels.DragonECS.Graphs.Internal
public static int length = 0; public static int length = 0;
public static void InitFor(int count) public static void InitFor(int count)
{ {
if (count <= length) { return; }
unchecked unchecked
{ {
//quasi random consts
const decimal G1 = 1.6180339887498948482045868383m; const decimal G1 = 1.6180339887498948482045868383m;
const uint Q32_MAX = uint.MaxValue; const uint Q32_MAX = uint.MaxValue;
const uint X1_Q32 = (uint)(1m / G1 * Q32_MAX) + 1; const uint X1_Q32 = (uint)(1m / G1 * Q32_MAX) + 1;
//count = GetHighBitNumber((uint)count) << 1;
if (count <= length) { return; }
if (hashes != null) if (hashes != null)
{ {
UnmanagedArrayUtility.Free(hashes); UnmanagedArrayUtility.Free(hashes);
} }
hashes = UnmanagedArrayUtility.New<int>(count); hashes = UnmanagedArrayUtility.New<int>(count);
uint state = 3571U; uint state = 3571U;
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
//state ^= state << 13;
//state ^= state >> 17;
//state ^= state << 5;
state = X1_Q32 * state; state = X1_Q32 * state;
hashes[i] = ((int)state) & 0x7FFFFFFF;
//int v = Mixing(i);
hashes[i] = (int)state;
} }
count = length; count = length;
} }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int Mixing(int v)
{
unchecked
{
int i = v;
v *= 3571;
//if(i % 3 == 0)
//{
// v ^= (v << 13) | 8191;
//}
//else
//{
// v ^= (v << 13);
//}
v ^= (v << 13);
v ^= v >> 17;
//if (i % 5 == 0)
//{
// v ^= (v << 5) | 15;
//}
//else
//{
// v ^= (v << 5);
//}
v ^= (v << 5);
//v = (v >> 28) + v ^ i;
return v;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetHighBitNumber(uint bits)
{
if (bits == 0)
{
return -1;
}
int bit = 0;
if ((bits & 0xFFFF0000) != 0)
{
bits >>= 16;
bit |= 16;
}
if ((bits & 0xFF00) != 0)
{
bits >>= 8;
bit |= 8;
}
if ((bits & 0xF0) != 0)
{
bits >>= 4;
bit |= 4;
}
if ((bits & 0xC) != 0)
{
bits >>= 2;
bit |= 2;
}
if ((bits & 0x2) != 0)
{
bit |= 1;
}
return bit;
}
} }
} }

View File

@ -41,17 +41,17 @@ namespace DCFApixels.DragonECS.Graphs.Internal
internal T* ptr; internal T* ptr;
internal int Length; internal int Length;
// public ref T this[int index] // public ref T this[int index]
// { // {
// [MethodImpl(MethodImplOptions.AggressiveInlining)] // [MethodImpl(MethodImplOptions.AggressiveInlining)]
// get // get
// { // {
//#if DEBUG //#if DEBUG
// if (index < 0 || index >= Length) { Throw.ArgumentOutOfRange(); } // if (index < 0 || index >= Length) { Throw.ArgumentOutOfRange(); }
//#endif //#endif
// return ref ptr[index]; // return ref ptr[index];
// } // }
// } // }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public UnsafeArray(int length) public UnsafeArray(int length)