daily update on 20231217 by nitload youmu
This commit is contained in:
@@ -0,0 +1,357 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StgSharp.Logic
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit, Size = 8)]
|
||||
internal struct LogSeperator
|
||||
{
|
||||
[FieldOffset(0)] public ulong all;
|
||||
[FieldOffset(0)] public long all_s;
|
||||
|
||||
[FieldOffset(0)] public uint low;
|
||||
[FieldOffset(4)] public uint high;
|
||||
|
||||
[FieldOffset(0)] public int low_s;
|
||||
[FieldOffset(4)] public int high_s;
|
||||
|
||||
public LogSeperator(uint high, uint low)
|
||||
{
|
||||
this.high = high;
|
||||
this.low = low;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A linear data structure with dynamic length.
|
||||
/// It contains a <see cref="List{T}"/> of <see cref="Array"/>,
|
||||
/// each <see cref="Array"/> is twice longer than the former one.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class DynamicArrayList<T>
|
||||
{
|
||||
private List<T[]> arrayIndexList;
|
||||
private LogSeperator indexpair;
|
||||
private int lastMain = 0;
|
||||
// main index to the last used element
|
||||
private int lastSub = 0;
|
||||
|
||||
private int length;
|
||||
private int subLength = 1;
|
||||
// sub index to the last used element
|
||||
private Queue<int> unusedMainIndex;
|
||||
private Queue<int> unusedSubIndex;
|
||||
public DynamicArrayList()
|
||||
{
|
||||
arrayIndexList = [new T[1]];
|
||||
length = 0;
|
||||
unusedMainIndex = new Queue<int>();
|
||||
unusedSubIndex = new Queue<int>();
|
||||
unusedMainIndex.Enqueue(0);
|
||||
unusedSubIndex.Enqueue(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Init a <see cref="DynamicArrayList{T}"/> with a certain amount of elements prepared.
|
||||
/// </summary>
|
||||
/// <param name="count">Amount of elements to be prepared.</param>
|
||||
public DynamicArrayList(int count)
|
||||
{
|
||||
arrayIndexList = new List<T[]>();
|
||||
length = count;
|
||||
unusedMainIndex = new();
|
||||
unusedSubIndex = new();
|
||||
|
||||
SeprateIndex(count);
|
||||
int subcount = 1;
|
||||
for (int i = 0; i < indexpair.high_s; i++)
|
||||
{
|
||||
arrayIndexList.Add(new T[count]);
|
||||
for (int j = 0; j < subcount; j++)
|
||||
{
|
||||
unusedMainIndex.Enqueue(i);
|
||||
unusedSubIndex.Enqueue(j);
|
||||
}
|
||||
count >>= 1;
|
||||
}
|
||||
if (indexpair.low_s != 0)
|
||||
{
|
||||
arrayIndexList.Add(new T[1 >> indexpair.high_s]);
|
||||
for (int j = 0; j < indexpair.high_s; j++)
|
||||
{
|
||||
unusedMainIndex.Enqueue(indexpair.high_s);
|
||||
unusedSubIndex.Enqueue(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal T this[long index]
|
||||
{
|
||||
get
|
||||
{
|
||||
indexpair.all_s = index;
|
||||
if (
|
||||
indexpair.low_s > lastSub ||
|
||||
indexpair.high_s > lastMain ||
|
||||
indexpair.low_s < 0 ||
|
||||
indexpair.high_s < 0)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
return arrayIndexList[indexpair.high_s][indexpair.low_s];
|
||||
}
|
||||
set
|
||||
{
|
||||
indexpair.all_s = index;
|
||||
if (
|
||||
indexpair.low_s > lastSub ||
|
||||
indexpair.high_s > lastMain ||
|
||||
indexpair.low_s < 0 ||
|
||||
indexpair.high_s < 0)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
arrayIndexList[indexpair.high_s][indexpair.low_s] = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index + 1 > length || index < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
SeprateIndex(index);
|
||||
return arrayIndexList[indexpair.high_s][indexpair.low_s];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (index + 1 > length || index < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
SeprateIndex(index);
|
||||
arrayIndexList[indexpair.high_s][indexpair.low_s] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public T this[uint index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index + 1 > length || index < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
SeprateIndex(index);
|
||||
return arrayIndexList[indexpair.high_s][indexpair.low_s];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (index + 1 > length || index < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
SeprateIndex(index);
|
||||
arrayIndexList[indexpair.high_s][indexpair.low_s] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Count => length;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Length of this <see cref="DynamicArrayList{T}"/>
|
||||
/// </summary>
|
||||
public int Length
|
||||
{
|
||||
get { return length; }
|
||||
}
|
||||
|
||||
public int Add(T item)
|
||||
{
|
||||
// this list is tite, all item is side by side
|
||||
if (unusedMainIndex.Count == 0)
|
||||
{
|
||||
// no extra space, a new sub array is needed
|
||||
if (lastSub + 1 == 1 << lastMain)
|
||||
{
|
||||
subLength <<= 1;
|
||||
arrayIndexList.Add(new T[subLength]);
|
||||
lastMain++;
|
||||
lastSub = 0;
|
||||
arrayIndexList[lastMain][0] = item;
|
||||
|
||||
length++;
|
||||
return length - 1;
|
||||
|
||||
}
|
||||
|
||||
length++;
|
||||
lastSub++;
|
||||
arrayIndexList[lastMain][lastSub] = item;
|
||||
return length - 1;
|
||||
}
|
||||
|
||||
length++;
|
||||
int main = unusedMainIndex.Dequeue();
|
||||
int sub = unusedSubIndex.Dequeue();
|
||||
arrayIndexList[main][sub] = item;
|
||||
|
||||
return sub + (1 << main);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
arrayIndexList.Clear();
|
||||
unusedMainIndex.Clear();
|
||||
unusedSubIndex.Clear();
|
||||
length = 0;
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
foreach (T[] list in arrayIndexList)
|
||||
{
|
||||
foreach (T i in list)
|
||||
{
|
||||
if (i.Equals(item))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int IndexOf(T item)
|
||||
{
|
||||
int index = 1;
|
||||
foreach (T[] list in arrayIndexList)
|
||||
{
|
||||
int subindex = 0;
|
||||
foreach (T i in list)
|
||||
{
|
||||
if (i.Equals(item))
|
||||
{
|
||||
return index + subindex - 1;
|
||||
}
|
||||
subindex++;
|
||||
}
|
||||
index <<= 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public bool Remove(T item)
|
||||
{
|
||||
int index = 0;
|
||||
foreach (T[] list in arrayIndexList)
|
||||
{
|
||||
int subindex = 0;
|
||||
foreach (T i in list)
|
||||
{
|
||||
if (i.Equals(item))
|
||||
{
|
||||
list[subindex] = default;
|
||||
if (subindex == lastSub && index == lastMain)
|
||||
{
|
||||
if (lastSub == 0)
|
||||
{
|
||||
lastMain = lastMain == 0 ? 0 : lastMain - 1;
|
||||
lastSub = arrayIndexList[lastMain].Length - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastSub--;
|
||||
}
|
||||
length--;
|
||||
return true;
|
||||
}
|
||||
unusedMainIndex.Enqueue(index);
|
||||
unusedSubIndex.Enqueue(subindex);
|
||||
return true;
|
||||
}
|
||||
subindex++;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
if (index > length || index < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
SeprateIndex(index);
|
||||
arrayIndexList[indexpair.high_s][indexpair.low] = default;
|
||||
|
||||
//the last element was removed.
|
||||
if (index + 1 == length)
|
||||
{
|
||||
//the last array can be disposed
|
||||
if (lastSub == 0)
|
||||
{
|
||||
arrayIndexList.RemoveAt(lastMain);
|
||||
lastMain--;
|
||||
lastSub = (length / 2) - 1;
|
||||
}
|
||||
length--;
|
||||
return;
|
||||
}
|
||||
|
||||
unusedMainIndex.Enqueue(indexpair.high_s);
|
||||
unusedSubIndex.Enqueue(indexpair.low_s);
|
||||
|
||||
}
|
||||
|
||||
public void ShowStructure()
|
||||
{
|
||||
foreach (T[] l in arrayIndexList)
|
||||
{
|
||||
foreach (T item in l)
|
||||
{
|
||||
Console.Write($"{item}\t");
|
||||
}
|
||||
Console.Write("\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
private void SeprateIndex(uint ulongIndex)
|
||||
{
|
||||
indexpair.high = ulongIndex;
|
||||
int mainindex = 0;
|
||||
while (indexpair.high > 1)
|
||||
{
|
||||
indexpair.all >>= 1;
|
||||
mainindex++;
|
||||
}
|
||||
indexpair.high_s = mainindex;
|
||||
indexpair.low >>= (int)(32 - mainindex);
|
||||
}
|
||||
|
||||
private void SeprateIndex(int longIndex)
|
||||
{
|
||||
indexpair.high_s = longIndex;
|
||||
int mainindex = 0;
|
||||
while (indexpair.high > 1)
|
||||
{
|
||||
indexpair.all >>= 1;
|
||||
mainindex++;
|
||||
}
|
||||
indexpair.high_s = mainindex;
|
||||
indexpair.low >>= (int)(32 - mainindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user