📄 btree.cs
字号:
namespace Perst.Impl
{
using System;
#if USE_GENERICS
using System.Collections.Generic;
#endif
using System.Collections;
using System.Diagnostics;
using Perst;
enum BtreeResult {
Done,
Overflow,
Underflow,
NotFound,
Duplicate,
Overwrite
}
class KeyBuilder
{
public static Key getKeyFromObject(object o)
{
if (o == null)
{
return null;
}
else if (o is byte)
{
return new Key((byte)o);
}
else if (o is sbyte)
{
return new Key((sbyte)o);
}
else if (o is short)
{
return new Key((short)o);
}
else if (o is ushort)
{
return new Key((ushort)o);
}
else if (o is int)
{
return new Key((int)o);
}
else if (o is uint)
{
return new Key((uint)o);
}
else if (o is long)
{
return new Key((long)o);
}
else if (o is ulong)
{
return new Key((ulong)o);
}
else if (o is float)
{
return new Key((float)o);
}
else if (o is double)
{
return new Key((double)o);
}
else if (o is bool)
{
return new Key((bool)o);
}
else if (o is char)
{
return new Key((char)o);
}
else if (o is String)
{
return new Key((String)o);
}
else if (o is DateTime)
{
return new Key((DateTime)o);
}
else if (o is byte[])
{
return new Key((byte[])o);
}
else if (o is object[])
{
return new Key((object[])o);
}
else if (o is Enum)
{
return new Key((Enum)o);
}
else if (o is IPersistent)
{
return new Key((IPersistent)o);
}
else if (o is Guid)
{
return new Key((Guid)o);
}
else if (o is Decimal)
{
return new Key((Decimal)o);
}
else if (o is IComparable)
{
return new Key((IComparable)o);
}
throw new StorageError(StorageError.ErrorCode.UNSUPPORTED_TYPE);
}
}
#if USE_GENERICS
interface Btree : IPersistent {
int markTree();
void export(XMLExporter exporter);
int insert(Key key, IPersistent obj, bool overwrite);
ClassDescriptor.FieldType FieldType {get;}
ClassDescriptor.FieldType[] FieldTypes {get;}
bool IsUnique{get;}
int compareByteArrays(Key key, Page pg, int i);
int HeaderSize{get;}
void init(Type cls, ClassDescriptor.FieldType[] types, string[] fieldNames, bool unique, long autoincCount);
}
class Btree<K,V>:PersistentCollection<V>, Index<K,V>, Btree where V:class,IPersistent
#else
class Btree:PersistentCollection, Index
#endif
{
internal int root;
internal int height;
internal ClassDescriptor.FieldType type;
internal int nElems;
internal bool unique;
[NonSerialized()]
internal int updateCounter;
internal static int Sizeof = ObjectHeader.Sizeof + 4 * 4 + 1;
internal Btree()
{
}
internal Btree(byte[] obj, int offs)
{
root = Bytes.unpack4(obj, offs);
offs += 4;
height = Bytes.unpack4(obj, offs);
offs += 4;
type = (ClassDescriptor.FieldType)Bytes.unpack4(obj, offs);
offs += 4;
nElems = Bytes.unpack4(obj, offs);
offs += 4;
unique = obj[offs] != 0;
}
#if USE_GENERICS
internal Btree(bool unique)
{
type = checkType(typeof(K));
this.unique = unique;
}
#else
internal Btree(Type cls, bool unique)
{
type = checkType(cls);
this.unique = unique;
}
#endif
#if USE_GENERICS
public override void OnLoad()
{
if (type != ClassDescriptor.getTypeCode(typeof(K))) {
throw new StorageError(StorageError.ErrorCode.INCOMPATIBLE_KEY_TYPE, typeof(K));
}
}
#endif
internal Btree(ClassDescriptor.FieldType type, bool unique)
{
this.type = type;
this.unique = unique;
}
public virtual void init(Type cls, ClassDescriptor.FieldType[] types, string[] fieldNames, bool unique, long autoincCount)
{
this.type = types[0];
this.unique = unique;
}
static protected ClassDescriptor.FieldType checkType(Type c)
{
ClassDescriptor.FieldType elemType = ClassDescriptor.getTypeCode(c);
if ((int)elemType > (int)ClassDescriptor.FieldType.tpOid
&& elemType != ClassDescriptor.FieldType.tpArrayOfByte
&& elemType != ClassDescriptor.FieldType.tpDecimal
&& elemType != ClassDescriptor.FieldType.tpGuid)
{
throw new StorageError(StorageError.ErrorCode.UNSUPPORTED_INDEX_TYPE, c);
}
return elemType;
}
public virtual int compareByteArrays(byte[] key, byte[] item, int offs, int length)
{
int n = key.Length >= length ? length : key.Length;
for (int i = 0; i < n; i++)
{
int diff = key[i] - item[i+offs];
if (diff != 0)
{
return diff;
}
}
return key.Length - length;
}
public override int Count
{
get
{
return nElems;
}
}
public bool IsUnique
{
get
{
return unique;
}
}
public int HeaderSize
{
get
{
return Sizeof;
}
}
public ClassDescriptor.FieldType FieldType
{
get
{
return type;
}
}
public virtual ClassDescriptor.FieldType[] FieldTypes
{
get
{
return new ClassDescriptor.FieldType[]{type};
}
}
public Type KeyType
{
get
{
#if USE_GENERICS
return typeof(K);
#else
return mapKeyType(type);
#endif
}
}
internal static Type mapKeyType(ClassDescriptor.FieldType type)
{
switch (type)
{
case ClassDescriptor.FieldType.tpBoolean:
return typeof(bool);
case ClassDescriptor.FieldType.tpSByte:
return typeof(sbyte);
case ClassDescriptor.FieldType.tpByte:
return typeof(byte);
case ClassDescriptor.FieldType.tpChar:
return typeof(char);
case ClassDescriptor.FieldType.tpShort:
return typeof(short);
case ClassDescriptor.FieldType.tpUShort:
return typeof(ushort);
case ClassDescriptor.FieldType.tpInt:
return typeof(int);
case ClassDescriptor.FieldType.tpUInt:
return typeof(uint);
case ClassDescriptor.FieldType.tpLong:
return typeof(long);
case ClassDescriptor.FieldType.tpULong:
return typeof(ulong);
case ClassDescriptor.FieldType.tpFloat:
return typeof(float);
case ClassDescriptor.FieldType.tpDouble:
return typeof(double);
case ClassDescriptor.FieldType.tpString:
return typeof(string);
case ClassDescriptor.FieldType.tpDate:
return typeof(DateTime);
case ClassDescriptor.FieldType.tpOid:
case ClassDescriptor.FieldType.tpObject:
return typeof(IPersistent);
case ClassDescriptor.FieldType.tpArrayOfByte:
return typeof(byte[]);
case ClassDescriptor.FieldType.tpGuid:
return typeof(Guid);
case ClassDescriptor.FieldType.tpDecimal:
return typeof(decimal);
case ClassDescriptor.FieldType.tpEnum:
return typeof(Enum);
default:
return typeof(IComparable);
}
}
#if USE_GENERICS
public V[] this[K from, K till]
#else
public IPersistent[] this[object from, object till]
#endif
{
get
{
return Get(from, till);
}
}
#if USE_GENERICS
public V this[K key]
#else
public IPersistent this[object key]
#endif
{
get
{
return Get(key);
}
set
{
Set(key, value);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -