refactoring

This commit is contained in:
Mikhail 2024-03-16 13:54:50 +08:00
parent 35285d8064
commit 4c6e0ed045
16 changed files with 51 additions and 423 deletions

View File

@ -1,4 +1,4 @@
using DCFApixels.DragonECS.Relations.Internal; using DCFApixels.DragonECS.Graphs.Internal;
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -223,8 +223,6 @@ namespace DCFApixels.DragonECS
{ {
foreach (var relEntityID in relEntityBuffer) foreach (var relEntityID in relEntityBuffer)
{ {
//var (startEntityID, endEntityID) = _arc._relEntityInfos[relEntityID];
//_arc.ClearRelation_Internal(startEntityID, endEntityID);
_arc.ClearRelation_Internal(relEntityID); _arc.ClearRelation_Internal(relEntityID);
} }
} }
@ -242,7 +240,7 @@ namespace DCFApixels.DragonECS
{ {
_arc = arc; _arc = arc;
_arc.StartWorld.AddListener(this); _arc.StartWorld.AddListener(this);
OnWorldResize(_arc.StartWorld.Capacity); //OnWorldResize(_arc.StartWorld.Capacity);
} }
public void Destroy() public void Destroy()
{ {
@ -264,7 +262,7 @@ namespace DCFApixels.DragonECS
{ {
_arc = arc; _arc = arc;
_arc.EndWorld.AddListener(this); _arc.EndWorld.AddListener(this);
OnWorldResize(_arc.EndWorld.Capacity); //OnWorldResize(_arc.EndWorld.Capacity);
} }
public void Destroy() public void Destroy()
{ {
@ -286,7 +284,7 @@ namespace DCFApixels.DragonECS
{ {
_arc = arc; _arc = arc;
_arc.StartWorld.AddListener(this); _arc.StartWorld.AddListener(this);
OnWorldResize(_arc.StartWorld.Capacity); //OnWorldResize(_arc.StartWorld.Capacity);
} }
public void Destroy() public void Destroy()
{ {

View File

@ -1,7 +0,0 @@
namespace DCFApixels.DragonECS
{
public static class EcsWorldConfigRelationsExtensions
{
}
}

View File

@ -1,5 +1,5 @@
using DCFApixels.DragonECS.Relations.Internal; using DCFApixels.DragonECS.Graphs.Internal;
using DCFApixels.DragonECS.Relations.Utils; using DCFApixels.DragonECS.Graphs.Utils;
using System; using System;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS

View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS.Relations.Internal namespace DCFApixels.DragonECS.Graphs.Internal
{ {
internal static class ArrayUtility internal static class ArrayUtility
{ {

View File

@ -3,9 +3,9 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using static DCFApixels.DragonECS.Relations.Internal.BitsUtility; using static DCFApixels.DragonECS.Graphs.Internal.BitsUtility;
namespace DCFApixels.DragonECS.Relations.Internal namespace DCFApixels.DragonECS.Graphs.Internal
{ {
internal unsafe static class BitsUtility internal unsafe static class BitsUtility
{ {

View File

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

View File

@ -6,9 +6,9 @@ using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS.Relations.Utils namespace DCFApixels.DragonECS.Graphs.Internal
{ {
public class SparseArray<TValue> internal class SparseArray<TValue>
{ {
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;

View File

@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using TValue = System.Int32; using TValue = System.Int32;
namespace DCFApixels.DragonECS.Relations.Internal namespace DCFApixels.DragonECS.Graphs.Internal
{ {
internal sealed unsafe class SparseMatrix internal sealed unsafe class SparseMatrix
{ {
@ -33,7 +33,6 @@ namespace DCFApixels.DragonECS.Relations.Internal
public int Capacity public int Capacity
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
//get { return _buckets.Length; }
get { return _capacity; } get { return _capacity; }
} }
#endregion #endregion
@ -43,15 +42,11 @@ namespace DCFApixels.DragonECS.Relations.Internal
public SparseMatrix(int minCapacity = MIN_CAPACITY) public SparseMatrix(int minCapacity = MIN_CAPACITY)
{ {
minCapacity = NormalizeCapacity(minCapacity); minCapacity = NormalizeCapacity(minCapacity);
//_buckets = new Basket[minCapacity];
//_buckets = new UnsafeArray<Basket>(minCapacity);
_buckets = UnmanagedArrayUtility.New<Basket>(minCapacity); _buckets = UnmanagedArrayUtility.New<Basket>(minCapacity);
for (int i = 0; i < minCapacity; i++) for (int i = 0; i < minCapacity; i++)
{ {
_buckets[i] = Basket.Empty; _buckets[i] = Basket.Empty;
} }
//_entries = new Entry[minCapacity];
//_entries = new UnsafeArray<Entry>(minCapacity, true);
_entries = UnmanagedArrayUtility.NewAndInit<Entry>(minCapacity); _entries = UnmanagedArrayUtility.NewAndInit<Entry>(minCapacity);
_modBitMask = (minCapacity - 1) & 0x7FFFFFFF; _modBitMask = (minCapacity - 1) & 0x7FFFFFFF;
@ -59,13 +54,10 @@ namespace DCFApixels.DragonECS.Relations.Internal
_freeList = 0; _freeList = 0;
_freeCount = 0; _freeCount = 0;
//
_capacity = minCapacity; _capacity = minCapacity;
} }
#endregion #endregion
#region Add/TryAdd/Set #region Add/TryAdd/Set
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Add(int x, int y, TValue value) public void Add(int x, int y, TValue value)
@ -74,7 +66,7 @@ namespace DCFApixels.DragonECS.Relations.Internal
#if DEBUG #if DEBUG
if (FindEntry(key) >= 0) if (FindEntry(key) >= 0)
{ {
throw new ArgumentException("Has(x, y) is true"); Throw.ArgumentException("Has(x, y) is true");
} }
#endif #endif
int targetBucket = key.yHash & _modBitMask; int targetBucket = key.yHash & _modBitMask;
@ -114,7 +106,6 @@ namespace DCFApixels.DragonECS.Relations.Internal
int index; int index;
if (_freeCount == 0) if (_freeCount == 0)
{ {
//if (_count == _entries.Length)
if (_count == _capacity) if (_count == _capacity)
{ {
Resize(); Resize();
@ -124,26 +115,23 @@ namespace DCFApixels.DragonECS.Relations.Internal
} }
else else
{ {
//_freeCount > 0
index = _freeList; index = _freeList;
_freeList = _entries[index].next; _freeList = _entries[index].next;
_freeCount--; _freeCount--;
} }
#if DEBUG #if DEBUG
if(_freeCount < 0) { throw new Exception(); } if(_freeCount < 0) { Throw.UndefinedException(); }
#endif #endif
ref Basket basket = ref _buckets[targetBucket]; ref Basket basket = ref _buckets[targetBucket];
ref Entry entry = ref _entries[index]; ref Entry entry = ref _entries[index];
entry.next = basket.index; entry.next = basket.index;
entry.key = key; entry.key = key;
entry.value = value; entry.value = value;
basket.count++; basket.count++;
basket.index = index; basket.index = index;
//Console.WriteLine($"{targetBucket} {basket.count}");
if (basket.count >= MAX_CHAIN_LENGTH && Count / Capacity >= 0.7f) if (basket.count >= MAX_CHAIN_LENGTH && Count / Capacity >= 0.7f)
{ {
@ -191,10 +179,7 @@ namespace DCFApixels.DragonECS.Relations.Internal
{ {
int index = FindEntry(x, y); int index = FindEntry(x, y);
#if DEBUG #if DEBUG
if(index < 0) if(index < 0) { Throw.KeyNotFound(); }
{
throw new KeyNotFoundException();
}
#endif #endif
return _entries[index].value; return _entries[index].value;
} }
@ -246,21 +231,15 @@ namespace DCFApixels.DragonECS.Relations.Internal
} }
#endregion #endregion
#region Clear #region Clear
public void Clear() public void Clear()
{ {
if (_count > 0) if (_count > 0)
{ {
//for (int i = 0; i < _buckets.Length; i++)
for (int i = 0; i < _capacity; i++) for (int i = 0; i < _capacity; i++)
{ {
_buckets[i] = Basket.Empty; _buckets[i] = Basket.Empty;
} }
//Array.Clear(_entries, 0, _count);
//UnsafeArray.Clear(ref _entries);
for (int i = 0; i < _capacity; i++) for (int i = 0; i < _capacity; i++)
{ {
_entries[i] = default; _entries[i] = default;
@ -274,26 +253,16 @@ namespace DCFApixels.DragonECS.Relations.Internal
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
private void Resize() private void Resize()
{ {
//int newSize = _buckets.Length << 1;
int newSize = _capacity << 1; int newSize = _capacity << 1;
_modBitMask = (newSize - 1) & 0x7FFFFFFF; _modBitMask = (newSize - 1) & 0x7FFFFFFF;
//Contract.Assert(newSize >= _entries.Length);
//Basket[] newBuckets = new Basket[newSize];
//UnsafeArray<Basket> newBuckets = new UnsafeArray<Basket>(newSize);
Basket* newBuckets = UnmanagedArrayUtility.New<Basket>(newSize); Basket* newBuckets = UnmanagedArrayUtility.New<Basket>(newSize);
//for (int i = 0; i < newBuckets.Length; i++)
for (int i = 0; i < _capacity; i++) for (int i = 0; i < _capacity; i++)
{ {
newBuckets[i] = Basket.Empty; newBuckets[i] = Basket.Empty;
} }
//Entry[] newEntries = new Entry[newSize];
//Array.Copy(_entries, 0, newEntries, 0, _count);
//UnsafeArray<Entry> newEntries = UnsafeArray<Entry>.Resize(_entries, newSize);
Entry* newEntries = UnmanagedArrayUtility.ResizeAndInit<Entry>(_entries, _capacity, newSize); Entry* newEntries = UnmanagedArrayUtility.ResizeAndInit<Entry>(_entries, _capacity, newSize);
for (int i = 0; i < _count; i++) for (int i = 0; i < _count; i++)
{ {
if (newEntries[i].key.yHash >= 0) if (newEntries[i].key.yHash >= 0)
@ -309,8 +278,6 @@ namespace DCFApixels.DragonECS.Relations.Internal
_entries = newEntries; _entries = newEntries;
_capacity = newSize; _capacity = newSize;
Console.WriteLine($"----- {Capacity} {Count}");
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -329,18 +296,13 @@ namespace DCFApixels.DragonECS.Relations.Internal
public int next; // Index of next entry, -1 if last public int next; // Index of next entry, -1 if last
public Key key; public Key key;
public TValue value; public TValue value;
public override string ToString() { return key.x == 0 ? "NULL" : value.ToString(); }
public override string ToString()
{
return key.x == 0 ? "NULL" : value.ToString();
}
} }
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)] [StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)]
public struct Basket public struct Basket
{ {
public static readonly Basket Empty = new Basket(-1, 0); public static readonly Basket Empty = new Basket(-1, 0);
public int index; public int index;
public int count; public int count;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -349,10 +311,7 @@ namespace DCFApixels.DragonECS.Relations.Internal
this.index = index; this.index = index;
this.count = length; this.count = length;
} }
public override string ToString() public override string ToString() { return index < 0 ? "NULL" : $"{index} {count}"; }
{
return index < 0 ? "NULL" : $"{index} {count}";
}
} }
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)] [StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)]
@ -368,32 +327,12 @@ namespace DCFApixels.DragonECS.Relations.Internal
this.yHash = yHash; this.yHash = yHash;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Key FromXY(int x, int y) public static Key FromXY(int x, int y) { return new Key(x, x ^ y ^ BitsUtility.NextXorShiftState(y)); }
{ public static bool operator ==(Key a, Key b) { return a.x == b.x && a.yHash == b.yHash; }
//return new Key(x, BitsUtility.NextXorShiftState(y)); public static bool operator !=(Key a, Key b) { return a.x != b.x || a.yHash != b.yHash; }
//return new Key(x, (~x) ^ y ^ 1_431_655_765); public override int GetHashCode() { return yHash; }
return new Key(x, x ^ y ^ BitsUtility.NextXorShiftState(y)); public bool Equals(Key other) { return this == other; }
} public override bool Equals(object obj) { return obj is Key && Equals((Key)obj); }
public static bool operator ==(Key a, Key b)
{
return a.x == b.x && a.yHash == b.yHash;
}
public static bool operator !=(Key a, Key b)
{
return a.x != b.x || a.yHash != b.yHash;
}
public override int GetHashCode()
{
return yHash;
}
public bool Equals(Key other)
{
return this == other;
}
public override bool Equals(object obj)
{
return obj is Key && Equals((Key)obj);
}
} }
#endregion #endregion
} }

View File

@ -5,7 +5,7 @@ using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS.Relations.Internal namespace DCFApixels.DragonECS.Graphs.Internal
{ {
internal unsafe static class UnsafeArray internal unsafe static class UnsafeArray
{ {

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 57bb7865029f870429c7b698334b116f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,34 +1,52 @@
using System; using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS.Relations.Internal namespace DCFApixels.DragonECS.Graphs.Internal
{ {
internal static class Throw internal static class Throw
{ {
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void RelationAlreadyExists()
{
throw new EcsRelationException("This relation already exists.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void UndefinedRelationException()
{
throw new EcsRelationException();
}
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
internal static void ArgumentNull() internal static void ArgumentNull()
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
internal static void ArgumentOutOfRange()
{
throw new ArgumentOutOfRangeException($"index is less than 0 or is equal to or greater than Count.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void UndefinedException() internal static void UndefinedException()
{ {
throw new Exception(); throw new Exception();
} }
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
internal static void ArgumentOutOfRange() internal static void Exception(string message)
{ {
throw new ArgumentOutOfRangeException(); throw new Exception(message);
} }
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
internal static void UndefinedRelationException() internal static void ArgumentException(string message)
{ {
throw new EcsRelationException(); throw new ArgumentException(message);
} }
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
internal static void RelationAlreadyExists() internal static void KeyNotFound()
{ {
throw new EcsRelationException("This relation already exists."); throw new KeyNotFoundException();
} }
} }
} }

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: e369fe57852b216439940cad19bbb5f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 5c8028c38ac28f84eac2ee5238fc3c2a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: cdd3589bd2d514845b172b2952fccc81
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,265 +0,0 @@
//SparseArray64. Analogous to Dictionary<long, T>, but faster.
//Benchmark result of indexer.get speed test with 300 elements:
//[Dictinary: 6.705us] [SparseArray64: 2.512us].
using DCFApixels.DragonECS.Relations.Internal;
using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS.Relations.Utils
{
internal unsafe class SparseArray64<TValue>
where TValue : unmanaged
{
public const int MIN_CAPACITY_BITS_OFFSET = 4;
public const int MIN_CAPACITY = 1 << MIN_CAPACITY_BITS_OFFSET;
private const int EMPTY = -1;
private UnsafeArray<int> _buckets;
private UnsafeArray<Entry> _entries;
private int _count;
private int _freeList;
private int _freeCount;
private int _modBitMask;
#region Properties
public TValue this[long keyX, long keyY]
{
get
{
//TODO Проверить необходимость проверки на Null
return _entries.ptr[FindEntry(keyX + (keyY << 32))].value;
}
set
{
Insert(keyX + (keyY << 32), value);
}
}
public TValue this[long key]
{
get
{
//TODO Проверить необходимость проверки на Null
return _entries.ptr[FindEntry(key)].value;
}
set
{
Insert(key, value);
}
}
public int Count
{
get { return _count; }
}
#endregion
#region Constructors
public SparseArray64(int minCapacity = MIN_CAPACITY)
{
minCapacity = NormalizeCapacity(minCapacity);
_buckets = new UnsafeArray<int>(minCapacity);
for (int i = 0; i < minCapacity; i++)
{
_buckets[i] = EMPTY;
}
_entries = new UnsafeArray<Entry>(minCapacity);
_modBitMask = (minCapacity - 1) & 0x7FFFFFFF;
}
#endregion
#region Add
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Add(long keyX, long keyY, TValue value) => Add(keyX + (keyY << 32), value);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Add(long key, TValue value)
{
#if DEBUG
if (Contains(key))
throw new ArgumentException("Contains(hashKey) is true");
#endif
Insert(key, value);
}
#endregion
#region Find/Insert/Remove
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int FindEntry(long key)
{
for (int i = _buckets[unchecked((int)key & _modBitMask)]; i >= 0; i = _entries[i].next)
if (_entries[i].hashKey == key) return i;
return -1;
}
private void Insert(long key, TValue value)
{
int targetBucket = unchecked((int)key & _modBitMask);
for (int i = _buckets[targetBucket]; i >= 0; i = _entries[i].next)
{
if (_entries[i].hashKey == key)
{
_entries[i].value = value;
return;
}
}
int index;
if (_freeCount > 0)
{
index = _freeList;
_freeList = _entries[index].next;
_freeCount--;
}
else
{
if (_count == _entries.Length)
{
Resize();
targetBucket = unchecked((int)key & _modBitMask);
}
index = _count++;
}
_entries[index].next = _buckets[targetBucket];
_entries[index].hashKey = key;
_entries[index].value = value;
_buckets[targetBucket] = index;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Remove(long keyX, long keyY) => Remove(keyX + (keyY << 32));
public bool Remove(long key)
{
int bucket = unchecked((int)key & _modBitMask);
int last = -1;
for (int i = _buckets[bucket]; i >= 0; last = i, i = _entries[i].next)
{
if (_entries[i].hashKey == key)
{
if (last < 0)
{
_buckets[bucket] = _entries[i].next;
}
else
{
_entries[last].next = _entries[i].next;
}
_entries[i].next = _freeList;
_entries[i].hashKey = -1;
_entries[i].value = default;
_freeList = i;
_freeCount++;
return true;
}
}
return false;
}
#endregion
#region TryGetValue
public bool TryGetValue(long key, out TValue value)
{
int index = FindEntry(key);
if (index < 0)
{
value = default;
return false;
}
value = _entries.ptr[index].value;
return true;
}
public bool TryGetValue(long keyX, long keyY, out TValue value)
{
int index = FindEntry(keyX + (keyY << 32));
if (index < 0)
{
value = default;
return false;
}
value = _entries.ptr[index].value;
return true;
}
#endregion
#region Contains
public bool Contains(long keyX, long keyY)
{
return FindEntry(keyX + (keyY << 32)) >= 0;
}
public bool Contains(long key)
{
return FindEntry(key) >= 0;
}
#endregion
#region Clear
public void Clear()
{
if (_count > 0)
{
for (int i = 0; i < _buckets.Length; i++)
{
_buckets[i] = -1;
}
for (int i = 0; i < _count; i++)
{
_entries[i] = default;
}
_count = 0;
}
}
#endregion
#region Resize
private void Resize()
{
int newSize = _buckets.Length << 1;
_modBitMask = (newSize - 1) & 0x7FFFFFFF;
Contract.Assert(newSize >= _entries.Length);
UnsafeArray<int> newBuckets = new UnsafeArray<int>(newSize);
for (int i = 0; i < newBuckets.Length; i++)
newBuckets[i] = EMPTY;
UnsafeArray<Entry> newEntries = UnsafeArray<Entry>.Resize(_entries, newSize);
//UnsafeArray<Entry> newEntries = new UnsafeArray<Entry>(newSize);
//Array.Copy(_entries, 0, newEntries, 0, _count);
for (int i = 0; i < _count; i++)
{
if (newEntries[i].hashKey >= 0)
{
int bucket = unchecked((int)newEntries[i].hashKey & _modBitMask);
newEntries[i].next = newBuckets[bucket];
newBuckets[bucket] = i;
}
}
_buckets = newBuckets;
_entries = newEntries;
}
private int NormalizeCapacity(int capacity)
{
int result = MIN_CAPACITY;
while (result < capacity) result <<= 1;
return result;
}
#endregion
#region Utils
[StructLayout(LayoutKind.Sequential, Pack = 4)]
[DebuggerDisplay("next{next} hashKey{hashKey} value{value}")]
private struct Entry
{
public int next; // Index of next entry, -1 if last
public long hashKey;
public TValue value;
}
#endregion
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: a5614297928ccbc479e9a0b7bd42df4b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: