CPF/CPF.ReoGrid/Data/JaggedTreeArray.cs
2024-06-24 10:15:59 +08:00

270 lines
4.7 KiB
C#

using System;
namespace CPF.ReoGrid.Data
{
[Serializable]
public sealed class JaggedTreeArray<T>
{
public JaggedTreeArray()
{
this.root.nodes = new JaggedTreeArray<T>.Node[1024][];
}
public int MaxRow
{
get
{
return this.maxRow;
}
set
{
this.maxRow = value;
}
}
public int MaxCol
{
get
{
return this.maxCol;
}
set
{
this.maxCol = value;
}
}
public T this[int row, int col]
{
get
{
JaggedTreeArray<T>.Node node = this.root;
int i = 1;
while (i > 0)
{
int num = (row >> 7 * i) % 1024;
JaggedTreeArray<T>.Node[] array = node.nodes[num];
bool flag = array == null;
T result;
if (flag)
{
result = default(T);
}
else
{
int num2 = (col >> 7 * i) % 128;
node = array[num2];
bool flag2 = node == null;
if (!flag2)
{
i--;
continue;
}
result = default(T);
}
return result;
}
T[] array2 = node.data[row % 1024];
bool flag3 = array2 == null;
if (flag3)
{
return default(T);
}
return array2[col % 128];
}
set
{
JaggedTreeArray<T>.Node node = this.root;
for (int i = 1; i > 0; i--)
{
int num = (row >> 7 * i) % 1024;
JaggedTreeArray<T>.Node[] array = node.nodes[num];
bool flag = array == null;
if (flag)
{
bool flag2 = value == null;
if (flag2)
{
return;
}
array = (node.nodes[num] = new JaggedTreeArray<T>.Node[128]);
}
int num2 = (col >> 7 * i) % 128;
JaggedTreeArray<T>.Node node2 = array[num2];
bool flag3 = node2 == null;
if (flag3)
{
bool flag4 = value == null;
if (flag4)
{
return;
}
node2 = (node.nodes[num][num2] = new JaggedTreeArray<T>.Node());
bool flag5 = i > 1;
if (flag5)
{
node2.nodes = new JaggedTreeArray<T>.Node[1024][];
}
}
node = node2;
}
bool flag6 = node.data == null;
if (flag6)
{
bool flag7 = value == null;
if (flag7)
{
return;
}
node.data = new T[1024][];
}
int num3 = row % 1024;
T[] array2 = node.data[num3];
bool flag8 = array2 == null;
if (flag8)
{
bool flag9 = value == null;
if (flag9)
{
return;
}
array2 = (node.data[num3] = new T[128]);
}
array2[col % 128] = value;
bool flag10 = value != null;
if (flag10)
{
bool flag11 = row > this.maxRow;
if (flag11)
{
this.maxRow = row;
}
bool flag12 = col > this.maxCol;
if (flag12)
{
this.maxCol = col;
}
return;
}
}
}
public long RowCapacity
{
get
{
return (long)Math.Pow(1024.0, 3.0);
}
}
public long ColCapacity
{
get
{
return (long)Math.Pow(128.0, 3.0);
}
}
internal bool IsPageNull(int row, int col)
{
JaggedTreeArray<T>.Node node = this.root;
int i = 1;
while (i > 0)
{
int num = (row >> 7 * i) % 1024;
JaggedTreeArray<T>.Node[] array = node.nodes[num];
bool flag = array == null;
bool result;
if (flag)
{
result = true;
}
else
{
int num2 = (col >> 7 * i) % 128;
node = array[num2];
bool flag2 = node == null;
if (!flag2)
{
i--;
continue;
}
result = true;
}
return result;
}
return node.data == null;
}
public void Iterate(Func<int, int, T, int> iterator)
{
this.Iterate(0, 0, this.maxRow + 1, this.maxCol + 1, true, iterator);
}
public void Iterate(int startRow, int startCol, int rows, int cols, bool ignoreNull, Func<int, int, T, int> iterator)
{
int num = startRow + rows;
int num2 = startCol + cols;
for (int i = startRow; i < num; i++)
{
int j = startCol;
while (j < num2)
{
bool flag = this.IsPageNull(i, j);
if (flag)
{
j += 128 - j % 128;
}
else
{
T t = this[i, j];
int num3 = 1;
bool flag2 = !ignoreNull || t != null;
if (flag2)
{
num3 = iterator(i, j, t);
bool flag3 = num3 <= 0;
if (flag3)
{
return;
}
}
j += num3;
}
}
}
}
internal void Reset()
{
this.root.nodes = new JaggedTreeArray<T>.Node[1024][];
this.maxCol = 0;
this.maxRow = 0;
}
public const int RowSize = 1024;
public const int RowBitLen = 7;
public const int ColSize = 128;
public const int ColBitLen = 7;
public const int MaxDepth = 2;
private JaggedTreeArray<T>.Node root = new JaggedTreeArray<T>.Node();
private int maxRow = -1;
private int maxCol = -1;
[Serializable]
public sealed class Node
{
internal JaggedTreeArray<T>.Node[][] nodes;
internal T[][] data;
}
}
}