270 lines
4.7 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|