Beispiel #1
0
 internal PersistentMapImpl(Storage storage, Type keyType, int initialSize)
     : base(storage)
 {
     type   = ClassDescriptor.getTypeCode(keyType);
     keys   = new IComparable[initialSize];
     values = storage.CreateLink(initialSize);
 }
Beispiel #2
0
        internal void exportMultiFieldIndex(int oid, byte[] data)
        {
            Btree btree = new Btree(data, ObjectHeader.Sizeof);

            storage.assignOid(btree, oid);
            writer.Write(" <Perst.Impl.BtreeMultiFieldIndex id=\"" + oid + "\" unique=\"" + (btree.unique ? '1' : '0')
                         + "\" class=");
            int offs    = exportString(data, Btree.Sizeof);
            int nFields = Bytes.unpack4(data, offs);

            offs += 4;
            for (int i = 0; i < nFields; i++)
            {
                writer.Write(" field" + i + "=");
                offs = exportString(data, offs);
            }
            writer.Write(">\n");
            int nTypes = Bytes.unpack4(data, offs);

            offs            += 4;
            compoundKeyTypes = new ClassDescriptor.FieldType[nTypes];
            for (int i = 0; i < nTypes; i++)
            {
                compoundKeyTypes[i] = (ClassDescriptor.FieldType)Bytes.unpack4(data, offs);
                offs += 4;
            }
            btree.export(this);
            compoundKeyTypes = null;
            writer.Write(" </Perst.Impl.BtreeMultiFieldIndex>\n");
        }
Beispiel #3
0
        private ThickFieldIndex(StorageImpl db, Type cls, string fieldName, KeyMember mbr)
            : base(db, mbr.type)
#endif
        {
            this.mbr       = mbr;
            this.cls       = cls;
            this.fieldName = fieldName;
            type           = ClassDescriptor.convertToNotNullable(ClassDescriptor.getTypeCode(mbr.type));
        }
Beispiel #4
0
 public override void init(Type cls, ClassDescriptor.FieldType type, string[] fieldNames, bool unique, long autoincCount)
 {
     this.cls          = cls;
     this.unique       = unique;
     this.fieldName    = fieldNames[0];
     this.className    = ClassDescriptor.getTypeName(cls);
     this.autoincCount = autoincCount;
     lookupField(fieldNames[0]);
     this.type = checkType(mbrType);
 }
 public override void init(Type cls, ClassDescriptor.FieldType type, string[] fieldNames, bool unique, long autoincCount)
 {
     this.cls        = cls;
     this.unique     = unique;
     this.fieldNames = fieldNames;
     this.className  = ClassDescriptor.getTypeName(cls);
     locateFields();
     this.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);
     }
 }
Beispiel #6
0
 internal void  exportAssoc(int oid, byte[] body, int offs, int size, ClassDescriptor.FieldType type)
 {
     writer.Write("  <ref id=\"" + oid + "\"");
     if ((exportedBitmap[oid >> 5] & (1 << (oid & 31))) == 0)
     {
         markedBitmap[oid >> 5] |= 1 << (oid & 31);
     }
     if (compoundKeyTypes != null)
     {
         exportCompoundKey(body, offs, size, type);
     }
     else
     {
         writer.Write(" key=\"");
         exportKey(body, offs, size, type);
         writer.Write("\"");
     }
     writer.Write("/>\n");
 }
Beispiel #7
0
        void exportCompoundKey(byte[] body, int offs, int size, ClassDescriptor.FieldType type)
        {
            Debug.Assert(type == ClassDescriptor.FieldType.tpArrayOfByte);
            int end = offs + size;

            for (int i = 0; i < compoundKeyTypes.Length; i++)
            {
                type = compoundKeyTypes[i];
                if (type == ClassDescriptor.FieldType.tpArrayOfByte || type == ClassDescriptor.FieldType.tpString)
                {
                    size  = Bytes.unpack4(body, offs);
                    offs += 4;
                }
                writer.Write(" key" + i + "=\"");
                offs = exportKey(body, offs, size, type);
                writer.Write("\"");
            }
            Debug.Assert(offs == end);
        }
 internal void exportCompoundIndex(int oid, byte[] data, string name) 
 { 
     Btree btree = createBtree(oid, data);
     name = exportIdentifier(name);
     writer.Write(" <" + name + " id=\"" + oid + "\" unique=\"" + (btree.IsUnique ? '1' : '0') + "\"");
     int offs = btree.HeaderSize;
     int nTypes = Bytes.unpack4(data, offs);
     offs += 4;
     compoundKeyTypes = new ClassDescriptor.FieldType[nTypes];
     for (int i = 0; i < nTypes; i++) 
     { 
         ClassDescriptor.FieldType type = (ClassDescriptor.FieldType)Bytes.unpack4(data, offs);
         compoundKeyTypes[i] = type;
         writer.Write(" type" + i + "=\"" + type + "\"");
         offs += 4;
     }
     writer.Write(">\n");
     btree.export(this); 
     compoundKeyTypes = null;
     writer.Write(" </" + name + ">\n");
 }
        private int packKeyPart(ByteBuffer buf, int dst, ClassDescriptor.FieldType type, object val)
        {
            switch (type)
            {
            case ClassDescriptor.FieldType.tpBoolean:
                dst = buf.packBool(dst, (bool)val);
                break;

            case ClassDescriptor.FieldType.tpByte:
                dst = buf.packI1(dst, (byte)val);
                break;

            case ClassDescriptor.FieldType.tpSByte:
                dst = buf.packI1(dst, (sbyte)val);
                break;

            case ClassDescriptor.FieldType.tpShort:
                dst = buf.packI2(dst, (short)val);
                break;

            case ClassDescriptor.FieldType.tpUShort:
                dst = buf.packI2(dst, (ushort)val);
                break;

            case ClassDescriptor.FieldType.tpChar:
                dst = buf.packI2(dst, (char)val);
                break;

            case ClassDescriptor.FieldType.tpInt:
            case ClassDescriptor.FieldType.tpOid:
            case ClassDescriptor.FieldType.tpEnum:
                dst = buf.packI4(dst, (int)val);
                break;

            case ClassDescriptor.FieldType.tpUInt:
                dst = buf.packI4(dst, (int)(uint)val);
                break;

            case ClassDescriptor.FieldType.tpObject:
                dst = buf.packI4(dst, val != null ? (int)((IPersistent)val).Oid : 0);
                break;

            case ClassDescriptor.FieldType.tpLong:
                dst = buf.packI8(dst, (long)val);
                break;

            case ClassDescriptor.FieldType.tpULong:
                dst = buf.packI8(dst, (long)(ulong)val);
                break;

            case ClassDescriptor.FieldType.tpDate:
                dst = buf.packDate(dst, (DateTime)val);
                break;

            case ClassDescriptor.FieldType.tpFloat:
                dst = buf.packF4(dst, (float)val);
                break;

            case ClassDescriptor.FieldType.tpDouble:
                dst = buf.packF8(dst, (double)val);
                break;

            case ClassDescriptor.FieldType.tpDecimal:
                dst = buf.packDecimal(dst, (decimal)val);
                break;

            case ClassDescriptor.FieldType.tpGuid:
                dst = buf.packGuid(dst, (Guid)val);
                break;

            case ClassDescriptor.FieldType.tpString:
                dst = buf.packString(dst, (string)val);
                break;

            case ClassDescriptor.FieldType.tpArrayOfByte:
                buf.extend(dst + 4);
                if (val != null)
                {
                    byte[] arr = (byte[])val;
                    int    len = arr.Length;
                    Bytes.pack4(buf.arr, dst, len);
                    dst += 4;
                    buf.extend(dst + len);
                    Array.Copy(arr, 0, buf.arr, dst, len);
                    dst += len;
                }
                else
                {
                    Bytes.pack4(buf.arr, dst, 0);
                    dst += 4;
                }
                break;

            default:
                Debug.Assert(false, "Invalid type");
                break;
            }
            return(dst);
        }
Beispiel #10
0
        internal void extract(Page pg, int offs, ClassDescriptor.FieldType type)
        {
            byte[] data = pg.data;

            switch (type)
            {
            case ClassDescriptor.FieldType.tpBoolean:
                key = new Key(data[offs] != 0);
                break;

            case ClassDescriptor.FieldType.tpSByte:
                key = new Key((sbyte)data[offs]);
                break;

            case ClassDescriptor.FieldType.tpByte:
                key = new Key(data[offs]);
                break;

            case ClassDescriptor.FieldType.tpShort:
                key = new Key(Bytes.unpack2(data, offs));
                break;

            case ClassDescriptor.FieldType.tpUShort:
                key = new Key((ushort)Bytes.unpack2(data, offs));
                break;

            case ClassDescriptor.FieldType.tpChar:
                key = new Key((char)Bytes.unpack2(data, offs));
                break;

            case ClassDescriptor.FieldType.tpInt:
                key = new Key(Bytes.unpack4(data, offs));
                break;

            case ClassDescriptor.FieldType.tpEnum:
            case ClassDescriptor.FieldType.tpUInt:
            case ClassDescriptor.FieldType.tpObject:
            case ClassDescriptor.FieldType.tpOid:
                key = new Key((uint)Bytes.unpack4(data, offs));
                break;

            case ClassDescriptor.FieldType.tpLong:
                key = new Key(Bytes.unpack8(data, offs));
                break;

            case ClassDescriptor.FieldType.tpDate:
            case ClassDescriptor.FieldType.tpULong:
                key = new Key((ulong)Bytes.unpack8(data, offs));
                break;

            case ClassDescriptor.FieldType.tpFloat:
                key = new Key(Bytes.unpackF4(data, offs));
                break;

            case ClassDescriptor.FieldType.tpDouble:
                key = new Key(Bytes.unpackF8(data, offs));
                break;

            case ClassDescriptor.FieldType.tpGuid:
                key = new Key(Bytes.unpackGuid(data, offs));
                break;

            case ClassDescriptor.FieldType.tpDecimal:
                key = new Key(Bytes.unpackDecimal(data, offs));
                break;

            default:
                Debug.Assert(false, "Invalid type");
                break;
            }
        }
        internal void  createIndex(String indexType)
        {
            XMLScanner.Token tkn;
            int oid = 0;
            bool     unique = false;
            String   className = null;
            String   fieldName = null;
            String[] fieldNames = null;
            long     autoinc = 0;
            String   type = null;
            ClassDescriptor.FieldType[] types = null;

            while ((tkn = scanner.scan()) == XMLScanner.Token.IDENT)
            {
                string attrName = scanner.Identifier;
                if (scanner.scan() != XMLScanner.Token.EQ || scanner.scan() != XMLScanner.Token.SCONST)
                {
                    throwException("Attribute value expected");
                }
                string attrValue = scanner.String;
                if (attrName.Equals("id"))
                {
                    oid = mapId(parseInt(attrValue));
                }
                else if (attrName.Equals("unique"))
                {
                    unique = parseInt(attrValue) != 0;
                }
                else if (attrName.Equals("class"))
                {
                    className = attrValue;
                }
                else if (attrName.Equals("type"))
                {
                    type = attrValue;
                }
                else if (attrName.Equals("autoinc"))
                {
                    autoinc = parseInt(attrValue);
                }
                else if (attrName.Equals("field"))
                {
                    fieldName = attrValue;
                }
                else if (attrName.StartsWith("field"))
                {
                    int fieldNo = Int32.Parse(attrName.Substring(5));
                    if (fieldNames == null || fieldNames.Length <= fieldNo) 
                    { 
                        String[] newFieldNames = new String[fieldNo+1];
                        if (fieldNames != null) 
                        { 
                            Array.Copy(fieldNames, 0, newFieldNames, 0, fieldNames.Length);
                        }
                        fieldNames = newFieldNames;
                     }
                     fieldNames[fieldNo] = attrValue;
                }
                else if (attrName.StartsWith("type"))
                {
                    int typeNo = Int32.Parse(attrName.Substring(4));
                    if (types == null || types.Length <= typeNo) 
                    { 
                        ClassDescriptor.FieldType[] newTypes = new ClassDescriptor.FieldType[typeNo+1];
                        if (types != null) 
                        { 
                            Array.Copy(types, 0, newTypes, 0, types.Length);
                        }
                        types = newTypes;
                     }
                     types[typeNo] = mapType(attrValue);
                }
            }
            if (tkn != XMLScanner.Token.GT)
            {
                throwException("Unclosed element tag");
            }
            if (oid == 0)
            {
                throwException("ID is not specified or index");
            }
#if USE_GENERICS
            ClassDescriptor desc = storage.getClassDescriptor(findClassByName(indexType));
            Btree btree = (Btree)desc.newInstance();
#else
            Btree btree = null;
#endif            
            if (className != null)
            {
                Type cls = findClassByName(className);
                if (fieldName != null) 
                { 
#if USE_GENERICS
                    btree.init(cls, null, new string[]{fieldName}, unique, autoinc);
#else
                    btree = indexType.StartsWith("Perst.Impl.BtreeCaseInsensitiveFieldIndex")
                        ? (Btree)new BtreeCaseInsensitiveFieldIndex(cls, fieldName, unique, autoinc)
                        : (Btree)new BtreeFieldIndex(cls, fieldName, unique, autoinc);
#endif
                } 
                else if (fieldNames != null) 
                { 
#if USE_GENERICS
                    btree.init(cls, null, fieldNames, unique, autoinc);
#else
                    btree = indexType.StartsWith("Perst.Impl.BtreeCaseInsensitiveMultiFieldIndex")
                        ? (Btree)new BtreeCaseInsensitiveMultiFieldIndex(cls, fieldNames, unique)
                        : (Btree)new BtreeMultiFieldIndex(cls, fieldNames, unique);
#endif
                } 
                else
                {
                    throwException("Field name is not specified for field index");
                }
            }
            else
            {
                if (types != null) 
                { 
#if USE_GENERICS
                    btree.init(null, types, null, unique, autoinc);
#else
                    btree = new BtreeCompoundIndex(types, unique);
#endif
                } 
                else if (type == null)
                {
                    if (indexType.StartsWith("Perst.Impl.PersistentSet")) 
                    { 
#if !USE_GENERICS
                        btree = new PersistentSet(unique);
#endif
                    } 
                    else 
                    {
                        throwException("Key type is not specified for index");
                    }
                } 
                else 
                {
                    if (indexType.StartsWith("org.garret.perst.impl.BitIndexImpl")) 
                    { 
#if !USE_GENERICS
                        btree = new BitIndexImpl();
#endif
                    } 
                    else 
                    { 
#if USE_GENERICS
                        btree.init(null, new ClassDescriptor.FieldType[]{mapType(type)}, null, unique, autoinc);
#else
                        btree = new Btree(mapType(type), unique);
#endif
                    }
                }
            }
            storage.AssignOid(btree, oid, false);
			
            while ((tkn = scanner.scan()) == XMLScanner.Token.LT)
            {
                if (scanner.scan() != XMLScanner.Token.IDENT || !scanner.Identifier.Equals("ref"))
                {
                    throwException("<ref> element expected");
                }
                XMLElement refElem = readElement("ref");
                Key key;
                if (fieldNames != null) 
                { 
                    String[] values = new String[fieldNames.Length];                
#if USE_GENERICS
                    types = btree.FieldTypes;
#else
                    types = ((BtreeMultiFieldIndex)btree).types;
#endif
                    for (int i = 0; i < values.Length; i++) 
                    { 
                        values[i] = getAttribute(refElem, "key"+i);
                    }
                    key = createCompoundKey(types, values);
                } 
                else if (types != null) 
                { 
                    String[] values = new String[fieldNames.Length];                
                    for (int i = 0; i < values.Length; i++) 
                    { 
                        values[i] = getAttribute(refElem, "key"+i);
                    }
                    key = createCompoundKey(types, values);
                } 
                else 
                { 
                    key = createKey(btree.FieldType, getAttribute(refElem, "key"));
                }
                object obj = new PersistentStub(storage, mapId(getIntAttribute(refElem, "id")));
                btree.insert(key, obj, false);
            }
            if (tkn != XMLScanner.Token.LTS 
                || scanner.scan() != XMLScanner.Token.IDENT 
                || !scanner.Identifier.Equals(indexType) 
                || scanner.scan() != XMLScanner.Token.GT)
            {
                throwException("Element is not closed");
            }
#if USE_GENERICS
            ByteBuffer buf = new ByteBuffer();
            buf.extend(ObjectHeader.Sizeof);
            int size = storage.packObject(btree, desc, ObjectHeader.Sizeof, buf);
            byte[] data = buf.arr;
            ObjectHeader.setSize(data, 0, size);
            ObjectHeader.setType(data, 0, desc.Oid);
#else
            byte[] data = storage.packObject(btree, false);
            int size = ObjectHeader.getSize(data, 0);
#endif
            long pos = storage.allocate(size, 0);
            storage.setPos(oid, pos | StorageImpl.dbModifiedFlag);
			
            storage.pool.put(pos & ~ StorageImpl.dbFlagsMask, data, size);
        }
Beispiel #12
0
        int exportKey(byte[] body, int offs, int size, ClassDescriptor.FieldType type)
        {
            switch (type)
            {
            case ClassDescriptor.FieldType.tpBoolean:
                writer.Write(body[offs++] != 0?"1":"0");
                break;

            case ClassDescriptor.FieldType.tpByte:
                writer.Write(System.Convert.ToString((byte)body[offs++]));
                break;

            case ClassDescriptor.FieldType.tpSByte:
                writer.Write(System.Convert.ToString((sbyte)body[offs++]));
                break;

            case ClassDescriptor.FieldType.tpChar:
                writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                offs += 2;
                break;

            case ClassDescriptor.FieldType.tpShort:
                writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                offs += 2;
                break;

            case ClassDescriptor.FieldType.tpUShort:
                writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                offs += 2;
                break;

            case ClassDescriptor.FieldType.tpInt:
                writer.Write(System.Convert.ToString(Bytes.unpack4(body, offs)));
                offs += 4;
                break;

            case ClassDescriptor.FieldType.tpUInt:
            case ClassDescriptor.FieldType.tpObject:
            case ClassDescriptor.FieldType.tpEnum:
                writer.Write(System.Convert.ToString((uint)Bytes.unpack4(body, offs)));
                offs += 4;
                break;

            case ClassDescriptor.FieldType.tpLong:
                writer.Write(System.Convert.ToString(Bytes.unpack8(body, offs)));
                offs += 8;
                break;

            case ClassDescriptor.FieldType.tpULong:
                writer.Write(System.Convert.ToString((ulong)Bytes.unpack8(body, offs)));
                offs += 8;
                break;

            case ClassDescriptor.FieldType.tpFloat:
                writer.Write(System.Convert.ToString(Bytes.unpackF4(body, offs)));
                offs += 4;
                break;

            case ClassDescriptor.FieldType.tpDouble:
                writer.Write(System.Convert.ToString(Bytes.unpackF8(body, offs)));
                offs += 8;
                break;

            case ClassDescriptor.FieldType.tpGuid:
                writer.Write(Bytes.unpackGuid(body, offs).ToString());
                offs += 16;
                break;

            case ClassDescriptor.FieldType.tpDecimal:
                writer.Write(Bytes.unpackDecimal(body, offs).ToString());
                offs += 16;
                break;

            case ClassDescriptor.FieldType.tpString:
                for (int i = 0; i < size; i++)
                {
                    exportChar((char)Bytes.unpack2(body, offs));
                    offs += 2;
                }
                break;

            case ClassDescriptor.FieldType.tpArrayOfByte:
                for (int i = 0; i < size; i++)
                {
                    byte b = body[offs++];
                    writer.Write(hexDigit[(b >> 4) & 0xF]);
                    writer.Write(hexDigit[b & 0xF]);
                }
                break;

            case ClassDescriptor.FieldType.tpDate:
                writer.Write(Bytes.unpackDate(body, offs).ToString());
                offs += 8;
                break;

            default:
                Debug.Assert(false, "Invalid type");
                break;
            }
            return(offs);
        }