Beispiel #1
0
 public virtual BitIndex CreateBitIndex()
 {
     lock (this)
     {
         if (!opened)
             throw new StorageError(StorageError.STORAGE_NOT_OPENED);
         BitIndex index = new BitIndexImpl();
         index.AssignOid(this, 0, false);
         return index;
     }
 }
Beispiel #2
0
 private void InitBlock(BitIndexImpl enclosingInstance)
 {
     this.enclosingInstance = enclosingInstance;
 }
Beispiel #3
0
        internal void CreateIndex(string indexType)
        {
            Btree btree = null;
            int tkn;
            int oid = 0;
            bool unique = false;
            string className = null;
            string fieldName = null;
            string[] fieldNames = null;
            long autoinc = 0;
            string type = null;
            while ((tkn = scanner.Scan()) == XMLScanner.XML_IDENT)
            {
                string attrName = scanner.Identifier;
                if (scanner.Scan() != XMLScanner.XML_EQ || scanner.Scan() != XMLScanner.XML_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.StartsWith("field"))
                {
                    int len = attrName.Length;
                    if (len == 5)
                    {
                        fieldName = attrValue;
                    }
                    else
                    {
                        try
                        {
                            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;
                        }
                        catch (FormatException)
                        {
                            ThrowException("Invalid field index");
                        }
                    }
                }
            }

            if (tkn != XMLScanner.XML_GT)
            {
                ThrowException("Unclosed element tag");
            }

            if (oid == 0)
            {
                ThrowException("ID is not specified or index");
            }

            if (className != null)
            {
                Type cls = ClassDescriptor.LoadClass(storage, className);
                if (fieldName != null)
                {
                    btree = new BtreeFieldIndex(cls, fieldName, unique, autoinc);
                }
                else if (fieldNames != null)
                {
                    btree = new BtreeMultiFieldIndex(cls, fieldNames, unique);
                }
                else
                {
                    ThrowException("Field name is not specified for field index");
                }
            }
            else
            {
                if (type == null)
                {
                    if (indexType.Equals("TenderBaseImpl.PersistentSet"))
                    {
                        btree = new PersistentSet();
                    }
                    else
                    {
                        ThrowException("Key type is not specified for index");
                    }
                }
                else
                {
                    if (indexType.Equals("TenderBaseImpl.BitIndexImpl"))
                    {
                        btree = new BitIndexImpl();
                    }
                    else
                    {
                        btree = new Btree(MapType(type), unique);
                    }
                }
            }
            storage.AssignOid(btree, oid);

            while ((tkn = scanner.Scan()) == XMLScanner.XML_LT)
            {
                if (scanner.Scan() != XMLScanner.XML_IDENT || !scanner.Identifier.Equals("ref"))
                {
                    ThrowException("<ref> element expected");
                }
                XMLElement ref_Renamed = ReadElement("ref");
                Key key = null;
                int mask = 0;
                if (fieldNames != null)
                {
                    string[] values = new string[fieldNames.Length];
                    int[] types = ((BtreeMultiFieldIndex) btree).types;
                    for (int i = 0; i < values.Length; i++)
                    {
                        values[i] = GetAttribute(ref_Renamed, "key" + i);
                    }
                    key = CreateCompoundKey(types, values);
                }
                else
                {
                    if (btree is BitIndex)
                    {
                        mask = GetIntAttribute(ref_Renamed, "key");
                    }
                    else
                    {
                        key = CreateKey(btree.type, GetAttribute(ref_Renamed, "key"));
                    }
                }
                IPersistent obj = new PersistentStub(storage, MapId(GetIntAttribute(ref_Renamed, "id")));
                if (btree is BitIndex)
                {
                    ((BitIndex) btree).Put(obj, mask);
                }
                else
                {
                    btree.Insert(key, obj, false);
                }
            }
            if (tkn != XMLScanner.XML_LTS || scanner.Scan() != XMLScanner.XML_IDENT || !scanner.Identifier.Equals(indexType) || scanner.Scan() != XMLScanner.XML_GT)
            {
                ThrowException("Element is not closed");
            }
            byte[] data = storage.PackObject(btree);
            int size = ObjectHeader.GetSize(data, 0);
            long pos = storage.Allocate(size, 0);
            storage.SetPos(oid, pos | StorageImpl.dbModifiedFlag);

            storage.pool.Put(pos & ~ StorageImpl.dbFlagsMask, data, size);
        }
Beispiel #4
0
            internal BitIndexIterator(BitIndexImpl enclosingInstance, int set_Renamed, int clear)
            {
                InitBlock(enclosingInstance);
                sp = 0;
                counter = Enclosing_Instance.updateCounter;
                if (Enclosing_Instance.height == 0)
                {
                    return;
                }
                int pageId = Enclosing_Instance.root;
                StorageImpl db = (StorageImpl) Enclosing_Instance.Storage;
                if (db == null)
                {
                    throw new StorageError(StorageError.DELETED_OBJECT);
                }
                int h = Enclosing_Instance.height;
                this.set_Renamed = set_Renamed;
                this.clear = clear;

                pageStack = new int[h];
                posStack = new int[h];

                while (true)
                {
                    pageStack[sp] = pageId;
                    Page pg = db.GetPage(pageId);
                    sp += 1;
                    if (--h == 0)
                    {
                        GotoNextItem(pg, 0);
                        break;
                    }

                    pageId = BitIndexPage.GetItem(pg, TenderBaseImpl.BitIndexImpl.BitIndexPage.maxItems - 1);
                    db.pool.Unfix(pg);
                }
            }