195 lines
3.4 KiB
C#
195 lines
3.4 KiB
C#
using System;
|
|
|
|
namespace CPF.ReoGrid.Data
|
|
{
|
|
[Serializable]
|
|
internal sealed class TreeArray<T>
|
|
{
|
|
public TreeArray() : this(16, 5)
|
|
{
|
|
}
|
|
|
|
public TreeArray(int nodeSize, int maxDepth)
|
|
{
|
|
this.nodeSize = nodeSize;
|
|
this.maxDepth = maxDepth;
|
|
this.capacity = (long)Math.Pow((double)nodeSize, (double)maxDepth);
|
|
}
|
|
|
|
public T this[int index]
|
|
{
|
|
get
|
|
{
|
|
TreeArray<T>.Node node = this.root;
|
|
for (int i = this.maxDepth; i > 0; i--)
|
|
{
|
|
int num = (index >> 4 * i) % this.nodeSize;
|
|
node = node.nodes[num];
|
|
bool flag = node == null;
|
|
if (flag)
|
|
{
|
|
return default(T);
|
|
}
|
|
}
|
|
return node.data[index % this.nodeSize];
|
|
}
|
|
set
|
|
{
|
|
TreeArray<T>.Node node = this.root;
|
|
for (int i = this.maxDepth; i > 0; i--)
|
|
{
|
|
int num = (index >> 4 * i) % this.nodeSize;
|
|
TreeArray<T>.Node node2 = node.nodes[num];
|
|
bool flag = node2 == null;
|
|
if (flag)
|
|
{
|
|
bool flag2 = value == null;
|
|
if (flag2)
|
|
{
|
|
return;
|
|
}
|
|
node2 = (node.nodes[num] = new TreeArray<T>.Node());
|
|
bool flag3 = i > 0;
|
|
if (flag3)
|
|
{
|
|
node2.nodes = new TreeArray<T>.Node[this.nodeSize];
|
|
}
|
|
}
|
|
node = node2;
|
|
}
|
|
bool flag4 = node.data == null;
|
|
if (flag4)
|
|
{
|
|
bool flag5 = value == null;
|
|
if (flag5)
|
|
{
|
|
return;
|
|
}
|
|
node.data = new T[this.nodeSize];
|
|
}
|
|
node.data[index % this.nodeSize] = value;
|
|
}
|
|
}
|
|
|
|
public void RemoveAt(int index)
|
|
{
|
|
this[index] = default(T);
|
|
}
|
|
|
|
public long Capacity
|
|
{
|
|
get
|
|
{
|
|
return this.capacity;
|
|
}
|
|
}
|
|
|
|
public bool IsPageNull(int index)
|
|
{
|
|
TreeArray<T>.Node node = this.root;
|
|
for (int i = this.maxDepth; i > 0; i--)
|
|
{
|
|
int num = (index >> 4 * i) % this.nodeSize;
|
|
node = node.nodes[num];
|
|
bool flag = node == null;
|
|
if (flag)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return node.data == null;
|
|
}
|
|
|
|
public void Iterate(int index, int count, bool ignoreNull, Func<int, T, bool> iterator)
|
|
{
|
|
int num = index + count;
|
|
bool flag = (long)num > this.capacity;
|
|
if (flag)
|
|
{
|
|
num = (int)this.capacity;
|
|
}
|
|
int i = index;
|
|
while (i < num)
|
|
{
|
|
bool flag2 = this.IsPageNull(i);
|
|
if (flag2)
|
|
{
|
|
i += this.nodeSize - i % this.nodeSize;
|
|
}
|
|
else
|
|
{
|
|
bool flag3 = !iterator(i, this[i]);
|
|
if (flag3)
|
|
{
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void IterateReverse(int index, int count, bool ignoreNull, Func<int, T, bool> iterator)
|
|
{
|
|
int num = index - count;
|
|
bool flag = num <= -1;
|
|
if (flag)
|
|
{
|
|
num = -1;
|
|
}
|
|
int i = index;
|
|
while (i > num)
|
|
{
|
|
bool flag2 = this.IsPageNull(i);
|
|
if (flag2)
|
|
{
|
|
i -= i % this.nodeSize;
|
|
}
|
|
else
|
|
{
|
|
bool flag3 = !iterator(i, this[i]);
|
|
if (flag3)
|
|
{
|
|
break;
|
|
}
|
|
i--;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void RemoveRange(int index, int count)
|
|
{
|
|
int num = index + count;
|
|
int i = index;
|
|
while (i < num)
|
|
{
|
|
bool flag = this.IsPageNull(i);
|
|
if (flag)
|
|
{
|
|
i += this.nodeSize - i % this.nodeSize;
|
|
}
|
|
else
|
|
{
|
|
this[i] = default(T);
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
private int nodeSize = 16;
|
|
|
|
private int maxDepth = 5;
|
|
|
|
private long capacity;
|
|
|
|
private TreeArray<T>.Node root = new TreeArray<T>.Node();
|
|
|
|
[Serializable]
|
|
public sealed class Node
|
|
{
|
|
internal TreeArray<T>.Node[] nodes;
|
|
|
|
internal T[] data = null;
|
|
}
|
|
}
|
|
}
|