📄 btree.cs
字号:
{
V[] arr = new V[nElems];
#else
public virtual IPersistent[] ToArray()
{
IPersistent[] arr = new IPersistent[nElems];
#endif
if (root != 0)
{
BtreePage.traverseForward((StorageImpl) Storage, root, type, height, arr, 0);
}
return arr;
}
public virtual Array ToArray(Type elemType)
{
Array arr = Array.CreateInstance(elemType, nElems);
if (root != 0)
{
BtreePage.traverseForward((StorageImpl) Storage, root, type, height, (IPersistent[])arr, 0);
}
return arr;
}
public override void Deallocate()
{
if (root != 0)
{
BtreePage.purge((StorageImpl) Storage, root, type, height);
}
base.Deallocate();
}
public void export(XMLExporter exporter)
{
if (root != 0)
{
BtreePage.exportPage((StorageImpl) Storage, exporter, root, type, height);
}
}
public int markTree()
{
return (root != 0) ? BtreePage.markPage((StorageImpl)Storage, root, type, height) : 0;
}
protected virtual object unpackEnum(int val)
{
// Base B-Tree class has no information about particular enum type
// so it is not able to correctly unpack enum key
return val;
}
internal object unpackKey(StorageImpl db, Page pg, int pos)
{
int offs = BtreePage.firstKeyOffs + pos*ClassDescriptor.Sizeof[(int)type];
byte[] data = pg.data;
switch (type)
{
case ClassDescriptor.FieldType.tpBoolean:
return data[offs] != 0;
case ClassDescriptor.FieldType.tpSByte:
return (sbyte)data[offs];
case ClassDescriptor.FieldType.tpByte:
return data[offs];
case ClassDescriptor.FieldType.tpShort:
return Bytes.unpack2(data, offs);
case ClassDescriptor.FieldType.tpUShort:
return (ushort)Bytes.unpack2(data, offs);
case ClassDescriptor.FieldType.tpChar:
return (char) Bytes.unpack2(data, offs);
case ClassDescriptor.FieldType.tpInt:
return Bytes.unpack4(data, offs);
case ClassDescriptor.FieldType.tpEnum:
return unpackEnum(Bytes.unpack4(data, offs));
case ClassDescriptor.FieldType.tpUInt:
return (uint)Bytes.unpack4(data, offs);
case ClassDescriptor.FieldType.tpOid:
case ClassDescriptor.FieldType.tpObject:
return db.lookupObject(Bytes.unpack4(data, offs), null);
case ClassDescriptor.FieldType.tpLong:
return Bytes.unpack8(data, offs);
case ClassDescriptor.FieldType.tpDate:
return new DateTime(Bytes.unpack8(data, offs));
case ClassDescriptor.FieldType.tpULong:
return (ulong)Bytes.unpack8(data, offs);
case ClassDescriptor.FieldType.tpFloat:
return Bytes.unpackF4(data, offs);
case ClassDescriptor.FieldType.tpDouble:
return Bytes.unpackF8(data, offs);
case ClassDescriptor.FieldType.tpGuid:
return Bytes.unpackGuid(data, offs);
case ClassDescriptor.FieldType.tpDecimal:
return Bytes.unpackDecimal(data, offs);
case ClassDescriptor.FieldType.tpString:
{
int len = BtreePage.getKeyStrSize(pg, pos);
offs = BtreePage.firstKeyOffs + BtreePage.getKeyStrOffs(pg, pos);
char[] sval = new char[len];
for (int j = 0; j < len; j++)
{
sval[j] = (char) Bytes.unpack2(pg.data, offs);
offs += 2;
}
return new String(sval);
}
case ClassDescriptor.FieldType.tpArrayOfByte:
{
return unpackByteArrayKey(pg, pos);
}
default:
Debug.Assert(false, "Invalid type");
return null;
}
}
protected virtual object unpackByteArrayKey(Page pg, int pos)
{
int len = BtreePage.getKeyStrSize(pg, pos);
int offs = BtreePage.firstKeyOffs + BtreePage.getKeyStrOffs(pg, pos);
byte[] val = new byte[len];
Array.Copy(pg.data, offs, val, 0, len);
return val;
}
public virtual IDictionaryEnumerator GetDictionaryEnumerator()
{
return GetDictionaryEnumerator(null, null, IterationOrder.AscentOrder);
}
#if USE_GENERICS
public override IEnumerator<V> GetEnumerator()
#else
public override IEnumerator GetEnumerator()
#endif
{
return GetEnumerator(null, null, IterationOrder.AscentOrder);
}
public int compareByteArrays(Key key, Page pg, int i)
{
return compareByteArrays((byte[])key.oval,
pg.data,
BtreePage.getKeyStrOffs(pg, i) + BtreePage.firstKeyOffs,
BtreePage.getKeyStrSize(pg, i));
}
#if USE_GENERICS
class BtreeSelectionIterator : IEnumerator<V>, IEnumerable<V>, IEnumerable, PersistentEnumerator
{
internal BtreeSelectionIterator(Btree<K,V> tree, Key from, Key till, IterationOrder order)
#else
class BtreeSelectionIterator : IEnumerable, PersistentEnumerator
{
internal BtreeSelectionIterator(Btree tree, Key from, Key till, IterationOrder order)
#endif
{
this.from = from;
this.till = till;
this.type = tree.type;
this.order = order;
this.tree = tree;
Reset();
}
#if USE_GENERICS
IEnumerator IEnumerable.GetEnumerator()
{
return this;
}
public IEnumerator<V> GetEnumerator()
#else
public IEnumerator GetEnumerator()
#endif
{
return this;
}
public virtual void Reset()
{
int i, l, r;
Page pg;
int height = tree.height;
int pageId = tree.root;
updateCounter = tree.updateCounter;
hasCurrent = false;
sp = 0;
if (height == 0)
{
return;
}
db = (StorageImpl)tree.Storage;
if (db == null)
{
throw new StorageError(Perst.StorageError.ErrorCode.DELETED_OBJECT);
}
pageStack = new int[height];
posStack = new int[height];
if (type == ClassDescriptor.FieldType.tpString)
{
if (order == IterationOrder.AscentOrder)
{
if (from == null)
{
while (--height >= 0)
{
posStack[sp] = 0;
pageStack[sp] = pageId;
pg = db.getPage(pageId);
pageId = BtreePage.getKeyStrOid(pg, 0);
end = BtreePage.getnItems(pg);
db.pool.unfix(pg);
sp += 1;
}
}
else
{
while (--height > 0)
{
pageStack[sp] = pageId;
pg = db.getPage(pageId);
l = 0;
r = BtreePage.getnItems(pg);
while (l < r)
{
i = (l+r) >> 1;
if (BtreePage.compareStr(from, pg, i) >= from.inclusion)
{
l = i + 1;
}
else
{
r = i;
}
}
Debug.Assert(r == l);
posStack[sp] = r;
pageId = BtreePage.getKeyStrOid(pg, r);
db.pool.unfix(pg);
sp += 1;
}
pageStack[sp] = pageId;
pg = db.getPage(pageId);
l = 0;
end = r = BtreePage.getnItems(pg);
while (l < r)
{
i = (l+r) >> 1;
if (BtreePage.compareStr(from, pg, i) >= from.inclusion)
{
l = i + 1;
}
else
{
r = i;
}
}
Debug.Assert(r == l);
if (r == end)
{
sp += 1;
gotoNextItem(pg, r-1);
}
else
{
posStack[sp++] = r;
db.pool.unfix(pg);
}
}
if (sp != 0 && till != null)
{
pg = db.getPage(pageStack[sp-1]);
if (-BtreePage.compareStr(till, pg, posStack[sp-1]) >= till.inclusion)
{
sp = 0;
}
db.pool.unfix(pg);
}
}
else
{ // descent order
if (till == null)
{
while (--height > 0)
{
pageStack[sp] = pageId;
pg = db.getPage(pageId);
posStack[sp] = BtreePage.getnItems(pg);
pageId = BtreePage.getKeyStrOid(pg, posStack[sp]);
db.pool.unfix(pg);
sp += 1;
}
pageStack[sp] = pageId;
pg = db.getPage(pageId);
posStack[sp++] = BtreePage.getnItems(pg)-1;
db.pool.unfix(pg);
}
else
{
while (--height > 0)
{
pageStack[sp] = pageId;
pg = db.getPage(pageId);
l = 0;
r = BtreePage.getnItems(pg);
while (l < r)
{
i = (l+r) >> 1;
if (BtreePage.compareStr(till, pg, i) >= 1-till.inclusion)
{
l = i + 1;
}
else
{
r = i;
}
}
Debug.Assert(r == l);
posStack[sp] = r;
pageId = BtreePage.getKeyStrOid(pg, r);
db.pool.unfix(pg);
sp += 1;
}
pageStack[sp] = pageId;
pg = db.getPage(pageId);
l = 0;
r = BtreePage.getnItems(pg);
while (l < r)
{
i = (l+r) >> 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -