remove useless

This commit is contained in:
Mikhail 2023-05-26 06:22:33 +08:00
parent 7cc02d00ba
commit d230afdeb7
3 changed files with 1 additions and 702 deletions

View File

@ -1,7 +1,4 @@
using System;
using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS.Utils
namespace DCFApixels.DragonECS.Utils
{
internal static class ArrayUtility
{
@ -15,34 +12,4 @@ namespace DCFApixels.DragonECS.Utils
array[i] = value;
}
}
internal static unsafe class UnmanagedArrayUtility
{
public static void* New<T>(int elementCount) where T : struct
{
return Marshal.AllocHGlobal(Marshal.SizeOf(typeof(T)) * elementCount).ToPointer();
}
public static void* NewAndInit<T>(int elementCount) where T : struct
{
int newSizeInBytes = Marshal.SizeOf(typeof(T)) * elementCount;
byte* newArrayPointer = (byte*)Marshal.AllocHGlobal(newSizeInBytes).ToPointer();
for (int i = 0; i < newSizeInBytes; i++)
*(newArrayPointer + i) = 0;
return newArrayPointer;
}
public static void Free(void* pointerToUnmanagedMemory)
{
Marshal.FreeHGlobal(new IntPtr(pointerToUnmanagedMemory));
}
public static void* Resize<T>(void* oldPointer, int newElementCount) where T : struct
{
return (Marshal.ReAllocHGlobal(new IntPtr(oldPointer),
new IntPtr(Marshal.SizeOf(typeof(T)) * newElementCount))).ToPointer();
}
}
}

View File

@ -1,259 +0,0 @@
//SparseArray. Analogous to Dictionary<int, T>, but faster.
//Benchmark result of indexer.get speed test with 300 elements:
//[Dictinary: 5.786us] [SparseArray: 2.047us].
using System;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS.Utils
{
public class SparseArray<TValue>
{
public const int MIN_CAPACITY_BITS_OFFSET = 4;
public const int MIN_CAPACITY = 1 << MIN_CAPACITY_BITS_OFFSET;
private const int EMPTY = -1;
private int[] _buckets = Array.Empty<int>();
private Entry[] _entries = Array.Empty<Entry>();
private int[] _dense;
private int _count;
private int _freeList;
private int _freeCount;
private int _modBitMask;
#region Properties
public ref TValue this[int key]
{
get => ref _entries[FindEntry(key)].value;
//set => Insert(key, value);
}
public int Count => _count;
#endregion
#region Constructors
public SparseArray(int minCapacity = MIN_CAPACITY)
{
minCapacity = NormalizeCapacity(minCapacity);
_buckets = new int[minCapacity];
for (int i = 0; i < minCapacity; i++)
_buckets[i] = EMPTY;
_entries = new Entry[minCapacity];
_modBitMask = (minCapacity - 1) & 0x7FFFFFFF;
}
#endregion
#region Add
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Add(int 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(int key)
{
for (int i = _buckets[key & _modBitMask]; i >= 0; i = _entries[i].next)
if (_entries[i].hashKey == key) return i;
return -1;
}
private void Insert(int key, TValue value)
{
int targetBucket = 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 = key & _modBitMask;
}
index = _count++;
}
_entries[index].next = _buckets[targetBucket];
_entries[index].hashKey = key;
_entries[index].value = value;
_buckets[targetBucket] = index;
}
public bool Remove(int key)
{
int bucket = 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(int key, out TValue value)
{
int index = FindEntry(key);
if (index < 0)
{
value = default;
return false;
}
value = _entries[index].value;
return true;
}
#endregion
#region Contains
public bool Contains(int 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;
}
Array.Clear(_entries, 0, _count);
_count = 0;
}
}
#endregion
#region Resize
private void Resize()
{
int newSize = _buckets.Length << 1;
_modBitMask = (newSize - 1) & 0x7FFFFFFF;
Contract.Assert(newSize >= _entries.Length);
int[] newBuckets = new int[newSize];
for (int i = 0; i < newBuckets.Length; i++)
newBuckets[i] = EMPTY;
Entry[] newEntries = new Entry[newSize];
Array.Copy(_entries, 0, newEntries, 0, _count);
for (int i = 0; i < _count; i++)
{
if (newEntries[i].hashKey >= 0)
{
int bucket = newEntries[i].hashKey % newSize;
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 Enumerator
// public Enumerator GetEnumerator() => new Enumerator(this);
// public struct Enumerator
// {
// private SparseArray<TValue> _source;
// private int index;
// private int curretnItmeIndex;
//
// public ref readonly TValue Current
// {
// get
// {
// return ref _source._entries[curretnItmeIndex].value;
// }
// }
//
// public Enumerator(SparseArray<TValue> source)
// {
// _source = source;
// index = 0;
// curretnItmeIndex = 0;
// }
//
// public bool MoveNext()
// {
// // Use unsigned comparison since we set index to dictionary.count+1 when the enumeration ends.
// // dictionary.count+1 could be negative if dictionary.count is Int32.MaxValue
// while ((uint)index < (uint)_source.count)
// {
// if (dictionary.entries[index].hashCode >= 0)
// {
// current = new KeyValuePair<TKey, TValue>(dictionary.entries[index].key, dictionary.entries[index].value);
// index++;
// return true;
// }
// index++;
// }
//
// index = dictionary.count + 1;
// current = new KeyValuePair<TKey, TValue>();
// return false;
// }
// }
// #endregion
#region Utils
[StructLayout(LayoutKind.Sequential, Pack = 4)]
private struct Entry
{
public int next; // Index of next entry, -1 if last
public int hashKey;
public TValue value;
}
#endregion
}
}

View File

@ -1,409 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
namespace DCFApixels.DragonECS.Utils
{
public class SparseSet : IEnumerable<int>, ICollection<int>, IReadOnlyCollection<int>
{
public const int DEFAULT_DENSE_CAPACITY = 8;
public const int DEFAULT_SPARSE_CAPACITY = 16;
public const int MIN_CAPACITY = 4;
public const int MAX_CAPACITY = int.MaxValue;
private int[] _dense;
private int[] _sparse;
private int _count;
#region Properties
public int Count
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _count;
}
public int CapacityDense
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _dense.Length;
}
public int CapacitySparse
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _sparse.Length;
}
public int this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
#if DEBUG
ThrowHalper.CheckOutOfRange(this, index);
#endif
return _dense[index];
}
}
#endregion
#region Constructors
public SparseSet() : this(DEFAULT_DENSE_CAPACITY, DEFAULT_SPARSE_CAPACITY) { }
public SparseSet(int denseCapacity, int sparseCapacity)
{
denseCapacity = denseCapacity < MIN_CAPACITY ? MIN_CAPACITY : NormalizeCapacity(denseCapacity);
sparseCapacity = sparseCapacity < MIN_CAPACITY ? MIN_CAPACITY : NormalizeCapacity(sparseCapacity);
_dense = new int[denseCapacity];
_sparse = new int[sparseCapacity];
Reset();
}
#endregion
#region Add/AddRange
public void Add<T>(int value, ref T[] normalizedArray)
{
Add(value);
Normalize(ref normalizedArray);
}
public void Add(int value)
{
#if DEBUG
ThrowHalper.CheckValueIsPositive(value);
ThrowHalper.CheckValueNotContained(this, value);
#endif
if (_count >= _dense.Length)
Array.Resize(ref _dense, _dense.Length << 1);
if (value >= _sparse.Length)
{
int neadedSpace = _sparse.Length;
while (value >= neadedSpace)
neadedSpace <<= 1;
int i = _sparse.Length;
Array.Resize(ref _sparse, neadedSpace);
//loop unwinding
for (; i < neadedSpace;)
{
_sparse[i++] = -1;
_sparse[i++] = -1;
_sparse[i++] = -1;
_sparse[i++] = -1;
}
}
_dense[_count] = value;
_sparse[value] = _count++;
}
public bool TryAdd<T>(int value, ref T[] normalizedArray)
{
if (Contains(value)) return false;
Add(value);
Normalize(ref normalizedArray);
return true;
}
public bool TryAdd(int value)
{
if (Contains(value)) return false;
Add(value);
return true;
}
public void AddRange<T>(IEnumerable<int> range, ref T[] normalizedArray)
{
AddRange(range);
Normalize(ref normalizedArray);
}
public void AddRange(IEnumerable<int> range)
{
foreach (var item in range)
{
if (Contains(item)) continue;
Add(item);
}
}
#endregion
#region Contains
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Contains(int value)
{
return value >= 0 && value < CapacitySparse && _sparse[value] >= 0;
}
#endregion
#region Remove
public void Remove(int value)
{
#if DEBUG
ThrowHalper.CheckValueContained(this, value);
#endif
_dense[_sparse[value]] = _dense[--_count];
_sparse[_dense[_count]] = _sparse[value];
_sparse[value] = -1;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryRemove(int value)
{
if (!Contains(value)) return false;
Remove(value);
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RemoveAt(int index)
{
#if DEBUG
ThrowHalper.CheckOutOfRange(this, index);
#endif
Remove(_dense[index]);
}
#endregion
#region Other
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Normalize<T>(ref T[] array)
{
if (array.Length < CapacityDense) Array.Resize(ref array, CapacityDense);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int IndexOf(int value)
{
if (value < 0 || !Contains(value)) return -1;
return _sparse[value];
}
public void Sort()
{
int increment = 0;
for (int i = 0; i < CapacitySparse; i++)
{
if (_sparse[i] < _count)
{
_sparse[i] = increment;
_dense[increment++] = i;
}
}
}
public void HardSort()
{
int inc = 0;
int inc2 = _count;
for (int i = 0; i < CapacitySparse; i++)
{
if (_sparse[i] >= 0)
{
_sparse[i] = inc;
_dense[inc++] = i;
}
else
{
_dense[inc2++] = i;
}
}
}
public void CopyTo(SparseSet other)
{
other._count = _count;
if (CapacitySparse != other.CapacitySparse)
Array.Resize(ref other._sparse, CapacitySparse);
if (CapacityDense != other.CapacityDense)
Array.Resize(ref other._dense, CapacityDense);
_sparse.CopyTo(other._sparse, 0);
_dense.CopyTo(other._dense, 0);
}
public void CopyTo(int[] array, int arrayIndex)
{
#if DEBUG
if (arrayIndex < 0) throw new ArgumentException("arrayIndex is less than 0");
if (arrayIndex + _count >= array.Length) throw new ArgumentException("The number of elements in the source List<T> is greater than the available space from arrayIndex to the end of the destination array.");
#endif
for (int i = 0; i < _count; i++, arrayIndex++)
{
array[arrayIndex] = this[i];
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int NormalizeCapacity(int value)
{
return value + (MIN_CAPACITY - (value % MIN_CAPACITY));
}
#endregion
#region Clear/Reset
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Clear() => _count = 0;
public void Reset()
{
Clear();
//loop unwinding
for (int i = 0; i < _sparse.Length;)
{
_sparse[i++] = -1;
_sparse[i++] = -1;
_sparse[i++] = -1;
_sparse[i++] = -1;
}
}
public void Reset(int newDenseCapacity, int newSparseCapacity)
{
newDenseCapacity = newDenseCapacity < MIN_CAPACITY ? MIN_CAPACITY : NormalizeCapacity(newDenseCapacity);
newSparseCapacity = newSparseCapacity < MIN_CAPACITY ? MIN_CAPACITY : NormalizeCapacity(newSparseCapacity);
if (CapacitySparse != newSparseCapacity)
Array.Resize(ref _sparse, newSparseCapacity);
if (CapacityDense != newDenseCapacity)
Array.Resize(ref _dense, newDenseCapacity);
Reset();
}
#endregion
#region Enumerator
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public RefEnumerator GetEnumerator() => new RefEnumerator(_dense, _count);
public ref struct RefEnumerator
{
private readonly int[] _dense;
private readonly int _count;
private int _index;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public RefEnumerator(int[] values, int count)
{
_dense = values;
_count = count;
_index = -1;
}
public int Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _dense[_index];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dispose() { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext() => ++_index < _count;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Reset() => _index = -1;
}
IEnumerator<int> IEnumerable<int>.GetEnumerator() => new Enumerator(_dense, _count);
IEnumerator IEnumerable.GetEnumerator() => new Enumerator(_dense, _count);
public struct Enumerator : IEnumerator<int> //to implement the IEnumerable interface and use the ref structure, 2 Enumerators were created.
{
private readonly int[] _dense;
private readonly int _count;
private int _index;
public Enumerator(int[] values, int count)
{
_dense = values;
_count = count;
_index = -1;
}
public int Current => _dense[_index];
object IEnumerator.Current => _dense[_index];
public void Dispose() { }
public bool MoveNext() => ++_index < _count;
public void Reset() => _index = -1;
}
#endregion
#region ICollection
bool ICollection<int>.IsReadOnly => false;
bool ICollection<int>.Remove(int value) => TryRemove(value);
#endregion
#region Debug
public string Log()
{
StringBuilder logbuild = new StringBuilder();
for (int i = 0; i < CapacityDense; i++)
{
logbuild.Append(_dense[i] + ", ");
}
logbuild.Append("\n\r");
for (int i = 0; i < CapacitySparse; i++)
{
logbuild.Append(_sparse[i] + ", ");
}
logbuild.Append("\n\r --------------------------");
logbuild.Append("\n\r");
for (int i = 0; i < CapacityDense; i++)
{
logbuild.Append((i < _count ? _dense[i].ToString() : "_") + ", ");
}
logbuild.Append("\n\r");
for (int i = 0; i < CapacitySparse; i++)
{
logbuild.Append((_sparse[i] >= 0 ? _sparse[i].ToString() : "_") + ", ");
}
logbuild.Append("\n\r Count: " + _count);
logbuild.Append("\n\r Capacity: " + CapacitySparse);
logbuild.Append("\n\r IsValide: " + IsValide_Debug());
logbuild.Append("\n\r");
return logbuild.ToString();
}
public bool IsValide_Debug()
{
bool isPass = true;
for (int index = 0; index < _count; index++)
{
int value = _dense[index];
isPass = isPass && _sparse[value] == index;
}
return isPass;
}
#if DEBUG
private static class ThrowHalper
{
public static void CheckCapacity(int capacity)
{
if (capacity < 0)
throw new ArgumentException("Capacity cannot be a negative number");
}
public static void CheckValueIsPositive(int value)
{
if (value < 0)
throw new ArgumentException("The SparseSet can only contain positive numbers");
}
public static void CheckValueContained(SparseSet source, int value)
{
if (!source.Contains(value))
throw new ArgumentException($"Value {value} is not contained");
}
public static void CheckValueNotContained(SparseSet source, int value)
{
if (source.Contains(value))
throw new ArgumentException($"Value {value} is already contained");
}
public static void CheckOutOfRange(SparseSet source, int index)
{
if (index < 0 || index >= source.Count)
throw new ArgumentOutOfRangeException($"Index {index} was out of range. Must be non-negative and less than the size of the collection.");
}
}
#endif
#endregion
}
}