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

📄 btree.cs

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