Exemple #1
0
        internal static OldBtreeResult remove(DatabaseImpl db, int pageId, OldBtree tree, OldBtreeKey rem, int height)
        {
            Page pg = db.getPage(pageId);
            try
            {
                int i, n = getnItems(pg), l = 0, r = n;

                if (tree.FieldType == ClassDescriptor.FieldType.tpString)
                {
                    while (l < r)
                    {
                        i = (l + r) >> 1;
                        if (compareStr(rem.key, pg, i) > 0)
                            l = i + 1;
                        else
                            r = i;
                    }
                    if (--height != 0)
                    {
                        do
                        {
                            switch (remove(db, getKeyStrOid(pg, r), tree, rem, height))
                            {
                                case OldBtreeResult.Underflow:
                                    db.pool.unfix(pg);
                                    pg = null;
                                    pg = db.putPage(pageId);
                                    return handlePageUnderflow(db, pg, r, tree.FieldType, rem, height);

                                case OldBtreeResult.Done:
                                    return OldBtreeResult.Done;

                                case OldBtreeResult.Overflow:
                                    db.pool.unfix(pg);
                                    pg = null;
                                    pg = db.putPage(pageId);
                                    return insertStrKey(db, pg, r, rem, height);

                            }
                        }
                        while (++r <= n);
                    }
                    else
                    {
                        while (r < n)
                        {
                            if (compareStr(rem.key, pg, r) == 0)
                            {
                                int oid = getKeyStrOid(pg, r);
                                if (oid == rem.oid || rem.oid == 0)
                                {
                                    rem.oldOid = oid;
                                    db.pool.unfix(pg);
                                    pg = null;
                                    pg = db.putPage(pageId);
                                    return removeStrKey(pg, r);
                                }
                            }
                            else
                            {
                                break;
                            }
                            r += 1;
                        }
                    }
                }
                else if (tree.FieldType == ClassDescriptor.FieldType.tpArrayOfByte)
                {
                    while (l < r)
                    {
                        i = (l + r) >> 1;
                        if (tree.compareByteArrays(rem.key, pg, i) > 0)
                            l = i + 1;
                        else
                            r = i;
                    }
                    if (--height != 0)
                    {
                        do
                        {
                            switch (remove(db, getKeyStrOid(pg, r), tree, rem, height))
                            {
                                case OldBtreeResult.Underflow:
                                    db.pool.unfix(pg);
                                    pg = null;
                                    pg = db.putPage(pageId);
                                    return handlePageUnderflow(db, pg, r, tree.FieldType, rem, height);

                                case OldBtreeResult.Done:
                                    return OldBtreeResult.Done;

                                case OldBtreeResult.Overflow:
                                    db.pool.unfix(pg);
                                    pg = null;
                                    pg = db.putPage(pageId);
                                    return insertByteArrayKey(db, pg, r, rem, height);

                            }
                        }
                        while (++r <= n);
                    }
                    else
                    {
                        while (r < n)
                        {
                            if (tree.compareByteArrays(rem.key, pg, r) == 0)
                            {
                                int oid = getKeyStrOid(pg, r);
                                if (oid == rem.oid || rem.oid == 0)
                                {
                                    rem.oldOid = oid;
                                    db.pool.unfix(pg);
                                    pg = null;
                                    pg = db.putPage(pageId);
                                    return removeByteArrayKey(pg, r);
                                }
                            }
                            else
                            {
                                break;
                            }
                            r += 1;
                        }
                    }
                }
                else // scalars
                {
                    int itemSize = ClassDescriptor.Sizeof[(int)tree.FieldType];
                    while (l < r)
                    {
                        i = (l + r) >> 1;
                        if (compare(rem.key, pg, i) > 0)
                            l = i + 1;
                        else
                            r = i;

                    }
                    if (--height == 0)
                    {
                        int oid = rem.oid;
                        while (r < n)
                        {
                            if (compare(rem.key, pg, r) == 0)
                            {
                                if (getReference(pg, maxItems - r - 1) == oid || oid == 0)
                                {
                                    rem.oldOid = getReference(pg, maxItems - r - 1);
                                    db.pool.unfix(pg);
                                    pg = null;
                                    pg = db.putPage(pageId);
                                    memcpy(pg, r, pg, r + 1, n - r - 1, itemSize);
                                    memcpy(pg, maxItems - n + 1, pg, maxItems - n, n - r - 1, 4);
                                    setnItems(pg, --n);
                                    return n * (itemSize + 4) < keySpace / 2 ? OldBtreeResult.Underflow : OldBtreeResult.Done;
                                }
                            }
                            else
                            {
                                break;
                            }
                            r += 1;
                        }
                        return OldBtreeResult.NotFound;
                    }
                    do
                    {
                        switch (remove(db, getReference(pg, maxItems - r - 1), tree, rem, height))
                        {
                            case OldBtreeResult.Underflow:
                                db.pool.unfix(pg);
                                pg = db.putPage(pageId);
                                return handlePageUnderflow(db, pg, r, tree.FieldType, rem, height);

                            case OldBtreeResult.Done:
                                return OldBtreeResult.Done;

                        }
                    }
                    while (++r <= n);
                }
                return OldBtreeResult.NotFound;
            }
            finally
            {
                if (pg != null)
                {
                    db.pool.unfix(pg);

                }
            }
        }
Exemple #2
0
        internal static bool find(DatabaseImpl db, int pageId, Key firstKey, Key lastKey, OldBtree tree, int height, ArrayList result)
        {
            Page pg = db.getPage(pageId);
            int l = 0, n = getnItems(pg), r = n;
            int oid;
            height -= 1;
            try
            {
                if (tree.FieldType == ClassDescriptor.FieldType.tpString)
                {
                    if (firstKey != null)
                    {
                        while (l < r)
                        {
                            int i = (l + r) >> 1;
                            if (compareStr(firstKey, pg, i) >= firstKey.inclusion)
                                l = i + 1;
                            else
                                r = i;
                        }
                        Debug.Assert(r == l);
                    }
                    if (lastKey != null)
                    {
                        if (height == 0)
                        {
                            while (l < n)
                            {
                                if (-compareStr(lastKey, pg, l) >= lastKey.inclusion)
                                    return false;
                                oid = getKeyStrOid(pg, l);
                                result.Add(db.lookupObject(oid, null));
                                l += 1;
                            }
                        }
                        else
                        {
                            do
                            {
                                if (!find(db, getKeyStrOid(pg, l), firstKey, lastKey, tree, height, result))
                                    return false;
                                if (l == n)
                                    return true;
                            }
                            while (compareStr(lastKey, pg, l++) >= 0);
                            return false;
                        }
                    }
                    else
                    {
                        if (height == 0)
                        {
                            while (l < n)
                            {
                                oid = getKeyStrOid(pg, l);
                                result.Add(db.lookupObject(oid, null));
                                l += 1;
                            }
                        }
                        else
                        {
                            do
                            {
                                if (!find(db, getKeyStrOid(pg, l), firstKey, lastKey, tree, height, result))
                                    return false;
                            }
                            while (++l <= n);
                        }
                    }
                }
                else if (tree.FieldType == ClassDescriptor.FieldType.tpArrayOfByte)
                {
                    if (firstKey != null)
                    {
                        while (l < r)
                        {
                            int i = (l + r) >> 1;
                            if (tree.compareByteArrays(firstKey, pg, i) >= firstKey.inclusion)
                                l = i + 1;
                            else
                                r = i;
                        }
                        Debug.Assert(r == l);
                    }
                    if (lastKey != null)
                    {
                        if (height == 0)
                        {
                            while (l < n)
                            {
                                if (-tree.compareByteArrays(lastKey, pg, l) >= lastKey.inclusion)
                                    return false;
                                oid = getKeyStrOid(pg, l);
                                result.Add(db.lookupObject(oid, null));
                                l += 1;
                            }
                        }
                        else
                        {
                            do
                            {
                                if (!find(db, getKeyStrOid(pg, l), firstKey, lastKey, tree, height, result))
                                    return false;
                                if (l == n)
                                    return true;
                            }
                            while (tree.compareByteArrays(lastKey, pg, l++) >= 0);
                            return false;
                        }
                    }
                    else
                    {
                        if (height == 0)
                        {
                            while (l < n)
                            {
                                oid = getKeyStrOid(pg, l);
                                result.Add(db.lookupObject(oid, null));
                                l += 1;
                            }
                        }
                        else
                        {
                            do
                            {
                                if (!find(db, getKeyStrOid(pg, l), firstKey, lastKey, tree, height, result))
                                    return false;
                            }
                            while (++l <= n);
                        }
                    }
                }
                else
                {
                    if (firstKey != null)
                    {
                        while (l < r)
                        {
                            int i = (l + r) >> 1;
                            if (compare(firstKey, pg, i) >= firstKey.inclusion)
                                l = i + 1;
                            else
                                r = i;
                        }
                        Debug.Assert(r == l);
                    }
                    if (lastKey != null)
                    {
                        if (height == 0)
                        {
                            while (l < n)
                            {
                                if (-compare(lastKey, pg, l) >= lastKey.inclusion)
                                    return false;
                                oid = getReference(pg, maxItems - 1 - l);
                                result.Add(db.lookupObject(oid, null));
                                l += 1;
                            }
                            return true;
                        }
                        else
                        {
                            do
                            {
                                if (!find(db, getReference(pg, maxItems - 1 - l), firstKey, lastKey, tree, height, result))
                                    return false;

                                if (l == n)
                                    return true;
                            }
                            while (compare(lastKey, pg, l++) >= 0);
                            return false;
                        }
                    }
                    if (height == 0)
                    {
                        while (l < n)
                        {
                            oid = getReference(pg, maxItems - 1 - l);
                            result.Add(db.lookupObject(oid, null));
                            l += 1;
                        }
                    }
                    else
                    {
                        do
                        {
                            if (!find(db, getReference(pg, maxItems - 1 - l), firstKey, lastKey, tree, height, result))
                                return false;
                        }
                        while (++l <= n);
                    }
                }
            }
            finally
            {
                db.pool.unfix(pg);
            }
            return true;
        }
Exemple #3
0
 internal static OldBtreeResult insert(DatabaseImpl db, int pageId, OldBtree tree, OldBtreeKey ins, int height, bool unique, bool overwrite)
 {
     Page pg = db.getPage(pageId);
     OldBtreeResult result;
     int l = 0, n = getnItems(pg), r = n;
     try
     {
         if (tree.FieldType == ClassDescriptor.FieldType.tpString)
         {
             while (l < r)
             {
                 int i = (l + r) >> 1;
                 if (compareStr(ins.key, pg, i) > 0)
                     l = i + 1;
                 else
                     r = i;
             }
             Debug.Assert(l == r);
             if (--height != 0)
             {
                 result = insert(db, getKeyStrOid(pg, r), tree, ins, height, unique, overwrite);
                 Debug.Assert(result != OldBtreeResult.NotFound);
                 if (result != OldBtreeResult.Overflow)
                 {
                     return result;
                 }
             }
             else if (r < n && compareStr(ins.key, pg, r) == 0)
             {
                 if (overwrite)
                 {
                     db.pool.unfix(pg);
                     pg = null;
                     pg = db.putPage(pageId);
                     setKeyStrOid(pg, r, ins.oid);
                     return OldBtreeResult.Overwrite;
                 }
                 else if (unique)
                 {
                     return OldBtreeResult.Duplicate;
                 }
             }
             db.pool.unfix(pg);
             pg = null;
             pg = db.putPage(pageId);
             return insertStrKey(db, pg, r, ins, height);
         }
         else if (tree.FieldType == ClassDescriptor.FieldType.tpArrayOfByte)
         {
             while (l < r)
             {
                 int i = (l + r) >> 1;
                 if (tree.compareByteArrays(ins.key, pg, i) > 0)
                     l = i + 1;
                 else
                     r = i;
             }
             Debug.Assert(l == r);
             if (--height != 0)
             {
                 result = insert(db, getKeyStrOid(pg, r), tree, ins, height, unique, overwrite);
                 Debug.Assert(result != OldBtreeResult.NotFound);
                 if (result != OldBtreeResult.Overflow)
                 {
                     return result;
                 }
             }
             else if (r < n && tree.compareByteArrays(ins.key, pg, r) == 0)
             {
                 if (overwrite)
                 {
                     db.pool.unfix(pg);
                     pg = null;
                     pg = db.putPage(pageId);
                     setKeyStrOid(pg, r, ins.oid);
                     return OldBtreeResult.Overwrite;
                 }
                 else if (unique)
                 {
                     return OldBtreeResult.Duplicate;
                 }
             }
             db.pool.unfix(pg);
             pg = null;
             pg = db.putPage(pageId);
             return insertByteArrayKey(db, pg, r, ins, height);
         }
         else
         {
             while (l < r)
             {
                 int i = (l + r) >> 1;
                 if (compare(ins.key, pg, i) > 0)
                     l = i + 1;
                 else
                     r = i;
             }
             Debug.Assert(l == r);
             /* insert before e[r] */
             if (--height != 0)
             {
                 result = insert(db, getReference(pg, maxItems - r - 1), tree, ins, height, unique, overwrite);
                 Debug.Assert(result != OldBtreeResult.NotFound);
                 if (result != OldBtreeResult.Overflow)
                     return result;
                 n += 1;
             }
             else if (r < n && compare(ins.key, pg, r) == 0)
             {
                 if (overwrite)
                 {
                     db.pool.unfix(pg);
                     pg = null;
                     pg = db.putPage(pageId);
                     setReference(pg, maxItems - r - 1, ins.oid);
                     return OldBtreeResult.Overwrite;
                 }
                 else if (unique)
                 {
                     return OldBtreeResult.Duplicate;
                 }
             }
             db.pool.unfix(pg);
             pg = null;
             pg = db.putPage(pageId);
             int itemSize = ClassDescriptor.Sizeof[(int)tree.FieldType];
             int max = keySpace / (4 + itemSize);
             if (n < max)
             {
                 memcpy(pg, r + 1, pg, r, n - r, itemSize);
                 memcpy(pg, maxItems - n - 1, pg, maxItems - n, n - r, 4);
                 ins.pack(pg, r);
                 setnItems(pg, getnItems(pg) + 1);
                 return OldBtreeResult.Done;
             }
             else
             {
                 /* page is full then divide page */
                 pageId = db.allocatePage();
                 Page b = db.putPage(pageId);
                 Debug.Assert(n == max);
                 int m = max / 2;
                 if (r < m)
                 {
                     memcpy(b, 0, pg, 0, r, itemSize);
                     memcpy(b, r + 1, pg, r, m - r - 1, itemSize);
                     memcpy(pg, 0, pg, m - 1, max - m + 1, itemSize);
                     memcpy(b, maxItems - r, pg, maxItems - r, r, 4);
                     ins.pack(b, r);
                     memcpy(b, maxItems - m, pg, maxItems - m + 1, m - r - 1, 4);
                     memcpy(pg, maxItems - max + m - 1, pg, maxItems - max, max - m + 1, 4);
                 }
                 else
                 {
                     memcpy(b, 0, pg, 0, m, itemSize);
                     memcpy(pg, 0, pg, m, r - m, itemSize);
                     memcpy(pg, r - m + 1, pg, r, max - r, itemSize);
                     memcpy(b, maxItems - m, pg, maxItems - m, m, 4);
                     memcpy(pg, maxItems - r + m, pg, maxItems - r, r - m, 4);
                     ins.pack(pg, r - m);
                     memcpy(pg, maxItems - max + m - 1, pg, maxItems - max, max - r, 4);
                 }
                 ins.oid = pageId;
                 ins.extract(b, firstKeyOffs + (m - 1) * itemSize, tree.FieldType);
                 if (height == 0)
                 {
                     setnItems(pg, max - m + 1);
                     setnItems(b, m);
                 }
                 else
                 {
                     setnItems(pg, max - m);
                     setnItems(b, m - 1);
                 }
                 db.pool.unfix(b);
                 return OldBtreeResult.Overflow;
             }
         }
     }
     finally
     {
         if (pg != null)
             db.pool.unfix(pg);
     }
 }