⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btreemultifieldindex.cs

📁 Perst开源实时数据库
💻 CS
📖 第 1 页 / 共 2 页
字号:
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 + -