?? btreemultifieldindex.cs
字號:
namespace Perst.Impl
{
using System;
#if USE_GENERICS
using System.Collections.Generic;
#endif
using System.Collections;
using System.Reflection;
using System.Diagnostics;
using Perst;
#if USE_GENERICS
class BtreeMultiFieldIndex<V>:Btree<object[],V>, MultiFieldIndex<V> where V:class,IPersistent
#else
class BtreeMultiFieldIndex:Btree, MultiFieldIndex
#endif
{
internal String className;
internal String[] fieldNames;
internal ClassDescriptor.FieldType[] types;
[NonSerialized()]
Type cls;
[NonSerialized()]
MemberInfo[] mbr;
internal BtreeMultiFieldIndex()
{
}
private void locateFields()
{
mbr = new MemberInfo[fieldNames.Length];
for (int i = 0; i < fieldNames.Length; i++)
{
Type compType;
mbr[i] = ClassDescriptor.lookupComponent(cls, fieldNames[i], out compType);
if (mbr[i] == null)
{
throw new StorageError(StorageError.ErrorCode.INDEXED_FIELD_NOT_FOUND, className + "." + fieldNames[i]);
}
}
}
public Type IndexedClass
{
get
{
return cls;
}
}
public MemberInfo KeyField
{
get
{
return mbr[0];
}
}
public MemberInfo[] KeyFields
{
get
{
return mbr;
}
}
public override ClassDescriptor.FieldType[] FieldTypes
{
get
{
return types;
}
}
public override void OnLoad()
{
cls = ClassDescriptor.lookup(Storage, className);
#if USE_GENERICS
if (cls != typeof(V))
{
throw new StorageError(StorageError.ErrorCode.INCOMPATIBLE_VALUE_TYPE, cls);
}
#endif
locateFields();
}
#if USE_GENERICS
internal BtreeMultiFieldIndex(string[] fieldNames, bool unique)
: this(typeof(V), fieldNames, unique)
{
}
#endif
internal BtreeMultiFieldIndex(Type cls, string[] fieldNames, bool unique)
{
init(cls, null, fieldNames, unique, 0);
}
public override void init(Type cls, ClassDescriptor.FieldType[] mfTypes, string[] fieldNames, bool unique, long autoincCount)
{
this.cls = cls;
this.unique = unique;
this.fieldNames = fieldNames;
this.className = ClassDescriptor.getTypeName(cls);
locateFields();
type = ClassDescriptor.FieldType.tpArrayOfByte;
types = new ClassDescriptor.FieldType[fieldNames.Length];
for (int i = 0; i < types.Length; i++)
{
Type mbrType = mbr[i] is FieldInfo ? ((FieldInfo)mbr[i]).FieldType : ((PropertyInfo)mbr[i]).PropertyType;
types[i] = checkType(mbrType);
}
}
public override int compareByteArrays(byte[] key, byte[] item, int offs, int lengtn)
{
int o1 = 0;
int o2 = offs;
byte[] a1 = key;
byte[] a2 = item;
for (int i = 0; i < types.Length && o1 < key.Length; i++)
{
int diff = 0;
switch (types[i])
{
case ClassDescriptor.FieldType.tpBoolean:
case ClassDescriptor.FieldType.tpByte:
diff = a1[o1++] - a2[o2++];
break;
case ClassDescriptor.FieldType.tpSByte:
diff = (sbyte)a1[o1++] - (sbyte)a2[o2++];
break;
case ClassDescriptor.FieldType.tpShort:
diff = Bytes.unpack2(a1, o1) - Bytes.unpack2(a2, o2);
o1 += 2;
o2 += 2;
break;
case ClassDescriptor.FieldType.tpUShort:
diff = (ushort)Bytes.unpack2(a1, o1) - (ushort)Bytes.unpack2(a2, o2);
o1 += 2;
o2 += 2;
break;
case ClassDescriptor.FieldType.tpChar:
diff = (char)Bytes.unpack2(a1, o1) - (char)Bytes.unpack2(a2, o2);
o1 += 2;
o2 += 2;
break;
case ClassDescriptor.FieldType.tpInt:
{
int i1 = Bytes.unpack4(a1, o1);
int i2 = Bytes.unpack4(a2, o2);
diff = i1 < i2 ? -1 : i1 == i2 ? 0 : 1;
o1 += 4;
o2 += 4;
break;
}
case ClassDescriptor.FieldType.tpUInt:
case ClassDescriptor.FieldType.tpEnum:
case ClassDescriptor.FieldType.tpObject:
case ClassDescriptor.FieldType.tpOid:
{
uint u1 = (uint)Bytes.unpack4(a1, o1);
uint u2 = (uint)Bytes.unpack4(a2, o2);
diff = u1 < u2 ? -1 : u1 == u2 ? 0 : 1;
o1 += 4;
o2 += 4;
break;
}
case ClassDescriptor.FieldType.tpLong:
{
long l1 = Bytes.unpack8(a1, o1);
long l2 = Bytes.unpack8(a2, o2);
diff = l1 < l2 ? -1 : l1 == l2 ? 0 : 1;
o1 += 8;
o2 += 8;
break;
}
case ClassDescriptor.FieldType.tpULong:
case ClassDescriptor.FieldType.tpDate:
{
ulong l1 = (ulong)Bytes.unpack8(a1, o1);
ulong l2 = (ulong)Bytes.unpack8(a2, o2);
diff = l1 < l2 ? -1 : l1 == l2 ? 0 : 1;
o1 += 8;
o2 += 8;
break;
}
case ClassDescriptor.FieldType.tpFloat:
{
float f1 = Bytes.unpackF4(a1, o1);
float f2 = Bytes.unpackF4(a2, o2);
diff = f1 < f2 ? -1 : f1 == f2 ? 0 : 1;
o1 += 4;
o2 += 4;
break;
}
case ClassDescriptor.FieldType.tpDouble:
{
double d1 = Bytes.unpackF8(a1, o1);
double d2 = Bytes.unpackF8(a2, o2);
diff = d1 < d2 ? -1 : d1 == d2 ? 0 : 1;
o1 += 8;
o2 += 8;
break;
}
case ClassDescriptor.FieldType.tpDecimal:
{
decimal d1 = Bytes.unpackDecimal(a1, o1);
decimal d2 = Bytes.unpackDecimal(a2, o2);
diff = d1.CompareTo(d2);
o1 += 16;
o2 += 16;
break;
}
case ClassDescriptor.FieldType.tpGuid:
{
Guid g1 = Bytes.unpackGuid(a1, o1);
Guid g2 = Bytes.unpackGuid(a2, o2);
diff = g1.CompareTo(g2);
o1 += 16;
o2 += 16;
break;
}
case ClassDescriptor.FieldType.tpString:
{
int len1 = Bytes.unpack4(a1, o1);
int len2 = Bytes.unpack4(a2, o2);
o1 += 4;
o2 += 4;
int len = len1 < len2 ? len1 : len2;
while (--len >= 0)
{
diff = (char)Bytes.unpack2(a1, o1) - (char)Bytes.unpack2(a2, o2);
if (diff != 0)
{
return diff;
}
o1 += 2;
o2 += 2;
}
diff = len1 - len2;
break;
}
case ClassDescriptor.FieldType.tpArrayOfByte:
{
int len1 = Bytes.unpack4(a1, o1);
int len2 = Bytes.unpack4(a2, o2);
o1 += 4;
o2 += 4;
int len = len1 < len2 ? len1 : len2;
while (--len >= 0)
{
diff = a1[o1++] - a2[o2++];
if (diff != 0)
{
return diff;
}
}
diff = len1 - len2;
break;
}
default:
Debug.Assert(false, "Invalid type");
break;
}
if (diff != 0)
{
return diff;
}
}
return 0;
}
protected override object unpackByteArrayKey(Page pg, int pos)
{
int offs = BtreePage.firstKeyOffs + BtreePage.getKeyStrOffs(pg, pos);
byte[] data = pg.data;
Object[] values = new Object[types.Length];
for (int i = 0; i < types.Length; i++)
{
Object v = null;
switch (types[i])
{
case ClassDescriptor.FieldType.tpBoolean:
v = data[offs++] != 0;
break;
case ClassDescriptor.FieldType.tpSByte:
v = (sbyte)data[offs++];
break;
case ClassDescriptor.FieldType.tpByte:
v = data[offs++];
break;
case ClassDescriptor.FieldType.tpShort:
v = Bytes.unpack2(data, offs);
offs += 2;
break;
case ClassDescriptor.FieldType.tpUShort:
v = (ushort)Bytes.unpack2(data, offs);
offs += 2;
break;
case ClassDescriptor.FieldType.tpChar:
v = (char) Bytes.unpack2(data, offs);
offs += 2;
break;
case ClassDescriptor.FieldType.tpInt:
v = Bytes.unpack4(data, offs);
offs += 4;
break;
case ClassDescriptor.FieldType.tpEnum:
v = Enum.ToObject(mbr[i] is FieldInfo ? ((FieldInfo)mbr[i]).FieldType : ((PropertyInfo)mbr[i]).PropertyType,
Bytes.unpack4(data, offs));
offs += 4;
break;
case ClassDescriptor.FieldType.tpUInt:
v = (uint)Bytes.unpack4(data, offs);
offs += 4;
break;
case ClassDescriptor.FieldType.tpOid:
case ClassDescriptor.FieldType.tpObject:
{
int oid = Bytes.unpack4(data, offs);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -