Examples of PageNumber


Examples of org.chaidb.db.index.btree.bufmgr.PageNumber

        // Get the latest data page within which we store data node
        boolean pageFixed = false;

        //add by stanley
        boolean hasPageForOverflow = false;
        PageNumber PgnForOverflow = null;
        DataPage DataPageForOverflow = null;
        Lock lockforOverflow = null;

        PageNumber latestDataPageNumber = buffer.getLatestDataPage(docid, pageNumber.getTreeId(), needLog ? new Integer(txnId) : null);

        Lock lock = null;
        boolean isValidPage;
        while (latestDataPageNumber != null && latestDataPageNumber.getPageNumber() > 0) {

            lock = BTreeLock.acquire(kContext, LockManager.LOCK_WAITING, latestDataPageNumber, LockManager.LOCK_WRITE);

            //Usually the page we get should not stay at freelist. But there is one exception:
            //With txn, each txn get LDP from GLDP list. Thus assuming
            //(1) txn1 get a LDP (pageNumber) from GLDP list and remove it from the list and
            //paused due to OS scheduler
            //(2) At this moment, txn2 deletes all nodes in this page
            //, finds that it is not a LDP by isLatestDataPage() (checking a page in its own LDP
            //list and GLDP list), then frees this page.
            //(3) Later txn1 resumes getting the LDP page with the pagenumber it got at (1), then
            // finds it has been freed. The following exception occurs!!!!!!!!
            //Hereby, when we get a LDP, we must catch this exception and get a new LDP. See codes

            try {
                isValidPage = true;
                dataPage = new DataPage(btreeSpec.btree.getBtreeId(), latestDataPageNumber, btreeSpec, buffer);
            } catch (ChaiDBException e) {
                if (e.getErrorCode() != ErrorCode.BTREE_USE_FREEPAGE) {
                    logger.error(e);
                    throw e;
                }
                isValidPage = false;
            }
            /* we abide by the following algorithm to get a data page
             * 1.if  the latest data page is big enough to hold all the new datanode then use it. else go to 2
             * 2.if a new data page is big enough to hold all the new datanode then use it. else go to 3
             * 3.if the latest data page is big enough to hold BTreeSpec.DATA_NODE_HEADER_SIZE + 4 then use it. else go to 2
             * 4.we new a data page and use it.
            */
            if (isValidPage && !dataPage.isOverflow()) {

                if (dataPage.getFreeSpace() >= newNodeSize) {

                    if (!(btreeSpec.btree.getType() == IDBIndex.ID2NODE_BTREE)) {
                        pageFixed = true;
                        break;
                    } else { // if this tree is special, this data page must
                        // belong to this doc if there are still data in
                        // this datapage
                        int docID = ((NodeId) key).getDocId();
                        if (dataPage.getCurrNodeNumbers() == 0) {
                            dataPage.setDocID(docID);
                            pageFixed = true;
                            break;
                        } else {
                            if (dataPage.isOfDoc(docID)) {
                                pageFixed = true;
                                break;
                            } else {
                                // release the data page

                                buffer.releasePage(latestDataPageNumber
                                        .getTreeId(), latestDataPageNumber, false);
                                // because we did NOT update this page, so we
                                // release it at once
                                BTreeLock.release(kContext, pageNumber
                                        .getTreeId(), lock);

                                latestDataPageNumber = buffer
                                        .getANewLatestDataPage(docid, pageNumber.getTreeId(), needLog ? new Integer(txnId) : null);
                            }
                        }
                    }

                } else if (!hasPageForOverflow && dataPage.getFreeSpace() >= BTreeSpec.DATA_NODE_HEADER_SIZE + 4) {

                    if (!(btreeSpec.btree.getType() == IDBIndex.ID2NODE_BTREE)) {
                        hasPageForOverflow = true;
                        PgnForOverflow = latestDataPageNumber;
                        DataPageForOverflow = dataPage;
                        lockforOverflow = lock;
                    } else { // if this tree is special, this data page must
                        // belong to this doc if there are still data in
                        // this datapage
                        int docID = ((NodeId) key).getDocId();
                        if (dataPage.getCurrNodeNumbers() == 0) {
                            dataPage.setDocID(docID);
                            hasPageForOverflow = true;
                            PgnForOverflow = latestDataPageNumber;
                            DataPageForOverflow = dataPage;
                            lockforOverflow = lock;
                        } else {
                            if (dataPage.isOfDoc(docID)) {
                                hasPageForOverflow = true;
                                PgnForOverflow = latestDataPageNumber;
                                DataPageForOverflow = dataPage;
                                lockforOverflow = lock;
                            } else {
                                // release the data page

                                buffer.releasePage(latestDataPageNumber
                                        .getTreeId(), latestDataPageNumber, false);
                                // because we did NOT update this page, so we
                                // release it at once
                                BTreeLock.release(kContext, pageNumber
                                        .getTreeId(), lock);
                            }
                        }
                    }
                    latestDataPageNumber = buffer.getANewLatestDataPage(docid, pageNumber.getTreeId(), needLog ? new Integer(txnId) : null);
                } else {
                    //The datapage is not suitable then release it
                    buffer.releasePage(latestDataPageNumber.getTreeId(), latestDataPageNumber, false);
                    //because we did NOT update this page, so we release it at once
                    BTreeLock.release(kContext, pageNumber.getTreeId(), lock);

                    latestDataPageNumber = buffer.getANewLatestDataPage(docid, pageNumber.getTreeId(), needLog ? new Integer(txnId) : null);
                }

            } else {
                //The datapage is not suitable then release it
                buffer.releasePage(latestDataPageNumber.getTreeId(), latestDataPageNumber, false);
                //because we did NOT update this page, so we release it at once
                BTreeLock.release(kContext, pageNumber.getTreeId(), lock);

                latestDataPageNumber = buffer.getANewLatestDataPage(docid, pageNumber.getTreeId(), needLog ? new Integer(txnId) : null);
            }
        }
        // size in byte of the node needed
        if (!pageFixed) {
            if (!hasPageForOverflow) {
                dataPage = DataPage.newPage(btreeSpec, buffer, false, kContext, docid);
                if (btreeSpec.btree.getType() == IDBIndex.ID2NODE_BTREE) dataPage.setDocID(docid);
            } else {
                if (newNodeSize <= BTreeSpec.PAGE_SIZE - BTreeSpec.PAGE_HEADER_SIZE) {
                    dataPage = DataPage.newPage(btreeSpec, buffer, false, kContext, docid);
                    if (btreeSpec.btree.getType() == IDBIndex.ID2NODE_BTREE) dataPage.setDocID(docid);

                    buffer.releasePage(PgnForOverflow.getTreeId(), PgnForOverflow, false);
                    // because we did NOT update this page, so we release it
                    // at once
                    BTreeLock.release(kContext, pageNumber.getTreeId(), lockforOverflow);

                } else {
                    dataPage = DataPageForOverflow;
                    latestDataPageNumber = PgnForOverflow;
                    lock = lockforOverflow;
                }
            }
            // lock=returnLock[0];
        } else {
            if (hasPageForOverflow) {
                buffer.releasePage(PgnForOverflow.getTreeId(), PgnForOverflow, false);
                //because we did NOT update this page, so we release it at once
                BTreeLock.release(kContext, pageNumber.getTreeId(), lockforOverflow);
            }
        }

        /*Modified by ben zhang at Aug, 12, 2002 */
        int nodeSize = BTreeSpec.NODE_HEADER_SIZE + key.size();

        /* begin : added by marriane 2001-12-28 for bind all insert
         * node log records
         */
        if (needLog) {
            bindAllInsertNodeLogRecords(dataPage, data, nodeSize, keyExist, key, txnId, nextIndex, currNode);
        }
        /* end : added by marriane 2001-12-28 for bind all insert
         * node log records
         */

        setUpperBound((short) (upperBound - btreeSpec.getLeafNodeSize()));
        setLowerBound((short) (lowerBound + 2));

        if (nextIndex < currNode) {
            System.arraycopy(page, (BTreeSpec.PAGE_HEADER_SIZE + nextIndex * 2), page, (BTreeSpec.PAGE_HEADER_SIZE + (nextIndex + 1) * 2), (currNode - nextIndex) * 2);
        }
        System.arraycopy(ByteTool.shortToBytes(upperBound), 0, page, (BTreeSpec.PAGE_HEADER_SIZE + nextIndex * 2), 2);
        // insert data node in data page
        /* Modified by ben zhang at Aug, 12, 2002 Pending issue
         * whether key is necessary
         */
        // @@@ Modified by Kurt

        byte[] newPageOff = null;
        short newOffset = 0;
        if (btreeSpec.btree.getType() == IDBIndex.HYPER_BTREE) {
            newPageOff = insertDupNode(dataPage, key, data, mode, kContext, -1);
        } else {
            newOffset = dataPage.insertNode(key.toBytes(), data, mode, kContext, -1, (byte) 0);
        }
//
//                short dataNodeOff=dataPage.insertNode(key,data,mode,kContext,-1);
        // @@@ Modified by Kurt

        // unfix the page
        buffer.releasePage(dataPage.pageNumber.getTreeId(), dataPage.pageNumber, true);

        // create a new BTree leaf node
        /*Modified by ben zhang at aug, 12, 2002 */
        leafNode = BTreeNode.createNewBTreeNode(this, upperBound, key.toBytes(), dataPage.getPageNumber());
        if (nodeSize <= btreeSpec.getLeafNodeSize()) {
            // if the page has enough space to hold the new node
            leafNode.setFlags((byte) 0);
        } else {
            // The leaf page doesn't have enough space to hold data
            leafNode.setFlags((byte) 3);
        }
        short dataNodeOff = 0;
        // @@@ Modified by Kurt
        if (btreeSpec.btree.getType() == IDBIndex.HYPER_BTREE) {
            if (newPageOff.length >= 4) {
                dataNodeOff = (short) ByteTool.bytesToInt(newPageOff, 0, btreeSpec.isMsbFirst());
                leafNode.setDataNodeOffset(dataNodeOff);
            }
            if (newPageOff.length == 8) {
                int newPageNum = ByteTool.bytesToInt(newPageOff, 4, btreeSpec.isMsbFirst());
                leafNode.setPageNumber(newPageNum);
            }
        } else {
            leafNode.setDataNodeOffset(newOffset);
        }
        // @@@ Modified by Kurt

        // We only need to store key in the leaf page now
        /*Modified by ben zhang at aug, 12, 2002 */
        leafNode.setInternalNode(key.toBytes(), kContext);
        //reput it to LDPL if this datapage is allocated this time
        if (!pageFixed) {
            if (dataPage.isOverflow()) {
                String details = Debug.getDebugInfo() + " want to put overflowpage[" + dataPage.pageNumber + "] to LDPL.";
                throw new ChaiDBException(ErrorCode.BTREE_DEBUG, details);
            }
            buffer.putLatestDataPage(docid, dataPage.pageNumber, needLog ? new Integer(txnId) : null);
        } else {
            /* if the following statement is not within "else",
             * the below line must be uncommented
             */
            if (needLog) BTreeLock.change(kContext, lock, latestDataPageNumber.getTreeId(), LockManager.LOCK_READ);
            else BTreeLock.release(kContext, pageNumber.getTreeId(), lock);

        }

    }
View Full Code Here

Examples of org.chaidb.db.index.btree.bufmgr.PageNumber

        BTreeNode leafNode;
        DataPage dataPage;
        // get the existing node
        leafNode = getNode(nextIndex);
        // insert data node in data page
        PageNumber dataPageNumber = new PageNumber(leafNode.getPageNumber());

        dataPage = new DataPage(btreeSpec.btree.getBtreeId(), dataPageNumber, btreeSpec, buffer);
        //logger.debug(""+ dataPageNumber );
        /* Modified by ben zhang at Aug, 12, 2002 Pending issue whether key is necessary */
//                    dataPage.insertNode(key.toBytes(), data, mode, kContext,
//                                        leafNode.getDataNodeOffset());
        /* Modified by Kurt Sung at Feb.24, 2003 to support duplicated key */
        if (btreeSpec.btree.getType() == IDBIndex.HYPER_BTREE) {
            insertDuplicatedNode(dataPage, key, data, mode, kContext, leafNode);
        } else {
            dataPage.insertNode(key.toBytes(), data, mode, kContext, leafNode.getDataNodeOffset(), (byte) 0);
        }

        // unfix this data page
        buffer.releasePage(dataPageNumber.getTreeId(), dataPageNumber, true);
    }
View Full Code Here

Examples of org.chaidb.db.index.btree.bufmgr.PageNumber

                newKey = insertWhenIsBTree(newPage, txnId, needLog, keyIndex, key, currNode, data, mode, kContext);

            }
            //====>>> 3a. if this is not root page
            if (this.prevPage.getPageNumber() != 0) {
                PageNumber newRoot = insertWhenNotRootPage(newPage, txnId, needLog, newKey, mode, kContext);

                return newRoot;
                //====>>> 3b. if this is root page
            } else {
                BTreePage rootPage = insertWhenIsRootPage(kContext, txnId, needLog, newKey, newPage, mode);
View Full Code Here

Examples of org.chaidb.db.index.btree.bufmgr.PageNumber

            System.arraycopy(ByteTool.intToBytes(pageNumber.getPageNumber()), 0, newV, BTreeSpec.OFF_NEXTPAGE, 4);
            BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, 0, oldV, newV, btreeSpec.btree.getType());
            lr.log();
        }
        rootPage.setInternal();
        rootPage.setPrevPage(new PageNumber(0)); // root
        rootPage.setNextPage(this.pageNumber); // leftmost
        rootPage.setLogInfo(txnId, needLog);

        rootPage.insertNode(newKey, ByteTool.intToBytes(newPage.pageNumber.getPageNumber()), mode, kContext);
        // set parent to the new rootPage
View Full Code Here

Examples of org.chaidb.db.index.btree.bufmgr.PageNumber

        // unfix and unlock this page and new Page
        buffer.releasePage(this.pageNumber.getTreeId(), this.pageNumber, true);
        buffer.releasePage(newPage.pageNumber.getTreeId(), newPage.pageNumber, true);

        PageNumber newRoot = parent.insert(newKey, ByteTool.intToBytes(newPage.pageNumber.getPageNumber()), mode, kContext);
        //unfix parent
        buffer.releasePage(btreeSpec.btree.getBtreeId(), parent.pageNumber, true);
        return newRoot;
    }
View Full Code Here

Examples of org.chaidb.db.index.btree.bufmgr.PageNumber

        return newRoot;
    }

    private Key insertWhenIsBTree(BTreePage newPage, int txnId, boolean needLog, KeyIndex keyIndex, Key key, int currNode, byte[] data, short mode, KernelContext kContext) throws ChaiDBException {
        Key newKey;
        PageNumber tmpPgNo;
        newPage.setLogInfo(txnId, needLog);
        newPage.setInternal();
        int indexOfInsert = keyIndex.keyIndex;
        // index of V', Tn/2T of keys in (key1, key2, keyn-1, key) >= V'
        int indexOfVictim = order / 2;
        // m is the index of the lowest key that >= V'
        int m = (indexOfInsert < indexOfVictim) ? (indexOfVictim - 1) : indexOfVictim;
        // V'
        /* Modified by ben zhang at Aug, 12, 2002 */
        Key tmpKey = getNode(m).getKey();
        newKey = (indexOfInsert == indexOfVictim) ? key : tmpKey;
        if (Debug.DEBUG_BTREEPAGE)
            logger.debug("m= " + m + " V'= " + new String(newKey.toBytes())); //Modified by ben zhang at Aug, 12, 2002 . Pending issue
        // insert datam, keym+1,...keyn-1 to new page
        // copy to new page
        int startCopyPoint = (indexOfInsert == indexOfVictim) ? m : m + 1;

        /************* The below is recorded in BTreeSplitLogRecord ******/
        /***************** Add by leon,2001-9-27 14:56 ********************/
        if (needLog) {
            int pgno = pageNumber.getPageNumber();
            int newpgno = newPage.getPageNumber().getPageNumber();

            BTreeSplitLogRecord lr = new BTreeSplitLogRecord(pageNumber.getTreeId(), pgno, txnId, (short) m, (short) startCopyPoint, newpgno, page, (short) btreeSpec.getNodeSize(), btreeSpec.btree.getType());
            lr.log();
        }
        /******************************************************************/

        for (int j = startCopyPoint; j < currNode; j++) {
            newPage.upperBound -= btreeSpec.getLeafNodeSize();
            BTreeNode node = getNode(j);
            // set child page's parent to new page
            BTreePage childPage = new BTreePage(btreeSpec.btree.getBtreeId(), node.getPageNumber(), btreeSpec, buffer);

            /********* add by leon *******/
            childPage.setLogInfo(txnId, needLog);
            /***************************/
            childPage.setPrevPage(newPage.pageNumber);

            // unfix and unlock child page
            buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
            System.arraycopy(page, node.getNodeOffset(), newPage.page, newPage.upperBound, btreeSpec.getLeafNodeSize());
            System.arraycopy(ByteTool.shortToBytes(newPage.upperBound), 0, newPage.page, newPage.lowerBound, 2);
            newPage.lowerBound += 2;
        }
        newPage.setLowerBound(newPage.lowerBound);
        newPage.setUpperBound(newPage.upperBound);

        if (indexOfInsert != indexOfVictim) {
            // leftmost is datam
            PageNumber leftmostPageNumber = getNode(m).getPageNumber();

            /********* add by leon *******/
            newPage.setLogInfo(txnId, needLog);
            /***************************/
            newPage.setNextPage(leftmostPageNumber);

            // set child page's parent to newPage
            BTreePage childPage = new BTreePage(btreeSpec.btree.getBtreeId(), leftmostPageNumber, btreeSpec, buffer);

            /********* add by leon *******/
            childPage.setLogInfo(txnId, needLog);
            /***************************/
            childPage.setPrevPage(newPage.pageNumber);

            // unfix child page
            buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
        } else {
            // leftmost is the new data
            if (data.length != 4) throw new ChaiDBException(ErrorCode.BTREE_INT_PAGE_NUMBER);
            PageNumber leftmostPageNumber = new PageNumber(ByteTool.bytesToInt(data, 0, btreeSpec.isMsbFirst()));
            leftmostPageNumber.setTreeId(btreeSpec.btree.getBtreeId());

            /********* add by leon *******/
            newPage.setLogInfo(txnId, needLog);
            /***************************/
            newPage.setNextPage(leftmostPageNumber);

            // set child page's parent to newPage
            BTreePage childPage = new BTreePage(leftmostPageNumber.getTreeId(), leftmostPageNumber, btreeSpec, buffer);

            /********* add by leon *******/
            childPage.setLogInfo(txnId, needLog);
            /***************************/
            childPage.setPrevPage(newPage.pageNumber);
            // unfix child page
            buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
        }
        // delete keym,...keyn-1 from the current page
        // remove from the current page
        byte[] tmp = new byte[m * btreeSpec.getLeafNodeSize()];
        byte[] ptr = new byte[m * 2];
        int k = 0;
        int p = 2 * (m - 1);
        short newUpperBound = (short) (btreeSpec.getPageSize() - btreeSpec.getLeafNodeSize() * m);
        for (int j = m - 1; j >= 0; j--) {
            System.arraycopy(page, getNodeOffset(j), tmp, k, btreeSpec.getLeafNodeSize());
            System.arraycopy(ByteTool.shortToBytes((short) (newUpperBound + k)), 0, ptr, p, 2);
            k += btreeSpec.getLeafNodeSize();
            p -= 2;
        }
        this.setUpperBound(newUpperBound);
        System.arraycopy(tmp, 0, page, this.upperBound, m * btreeSpec.getLeafNodeSize());
        System.arraycopy(ptr, 0, page, BTreeSpec.PAGE_HEADER_SIZE, 2 * m);
        this.setLowerBound((short) (BTreeSpec.PAGE_HEADER_SIZE + 2 * m));
        // insert the new node
        /*Modified by Ben Zhang at Aug, 12, 2002*/
        int cmp = key.compareTo(newKey);
        if (cmp < 0) {
            this.insertNode(key, data, mode, kContext);

            tmpPgNo = new PageNumber(ByteTool.bytesToInt(data, 0, btreeSpec.isMsbFirst()));
            tmpPgNo.setTreeId(btreeSpec.btree.getBtreeId());

            // change childPage's parent
            BTreePage childPage = new BTreePage(btreeSpec.btree.getBtreeId(), new PageNumber(ByteTool.bytesToInt(data, 0, btreeSpec.isMsbFirst())), btreeSpec, buffer);

            /********* add by leon *******/
            childPage.setLogInfo(txnId, needLog);
            /***************************/
            childPage.setPrevPage(this.pageNumber);

            // unfix childPage
            buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
        } else if (cmp > 0) {
            newPage.insertNode(key, data, mode, kContext);

            tmpPgNo = new PageNumber(ByteTool.bytesToInt(data, 0, btreeSpec.isMsbFirst()));
            tmpPgNo.setTreeId(btreeSpec.btree.getBtreeId());
            // change childPage's parent
            BTreePage childPage = new BTreePage(btreeSpec.btree.getBtreeId(), tmpPgNo, btreeSpec, buffer);

            /********* add by leon *******/
 
View Full Code Here

Examples of org.chaidb.db.index.btree.bufmgr.PageNumber

        this.setNextPage(newPage.pageNumber);
        return newKey;
    }

    private void insertWhenCurNodeLessThanOrder(Key key, byte[] data, short mode, KernelContext kContext, int txnId, boolean needLog) throws ChaiDBException {
        PageNumber tmpPgNo;
        // the page has enough space to store the new node
        insertNode(key, data, mode, kContext);

        if (isBTree() && !isLeaf()) {
            tmpPgNo = new PageNumber(ByteTool.bytesToInt(data, 0, btreeSpec.isMsbFirst()));
            tmpPgNo.setTreeId(btreeSpec.btree.getBtreeId());
            //Because once the upper page is locked, Others later coming
            //must be blocked at upper page. And the former who have
            //already entered, will NOT change children's previous page.
            //For BTree page, ONLY at SPLIT or MERGE condition, one's
            //previous page can be changed. So, because there is no
View Full Code Here

Examples of org.chaidb.db.index.btree.bufmgr.PageNumber

                if (node.getNodeOffset() == upperBound) upperBoundNodeIndex = i;
                /*Modified by ben zhang at aug, 12, 2002 */
                Key tmpKey = node.getKey();
                if (tmpKey.compareTo(key) == 0) {

                    PageNumber overflowPageNumber = null;
                    if (node.isOverflowKey()) {
                        //remember the overflowpage before overriding this node
                        overflowPageNumber = new PageNumber(ByteTool.bytesToInt(page, node.getNodeOffset() + BTreeSpec
                                .NODE_HEADER_SIZE, btreeSpec.isMsbFirst()));
                        overflowPageNumber.setTreeId(btreeSpec.btree.getBtreeId());
                    }

                    // 1. move the upperBound node to occupy the space
                    int nodeSize = btreeSpec.getInternalNodeSize();
                    if (needLog) {
View Full Code Here

Examples of org.chaidb.db.index.btree.bufmgr.PageNumber

     */
    //This method will not change the page's fixed count.
    public OperResult delete(Key key, KernelContext kContext) throws ChaiDBException {
        int txnId = kContext.getLocker();
        boolean needLog = kContext.getNeedLog();
        PageNumber tmpPgNo = null;
        OperResult result;

        try {
            /********* add by leon *********/
            setLogInfo(txnId, needLog);
            /*****************************/

            // delete node from page
            if (!deleteNode(key, kContext)) {
                return new OperResult(false, null);
            }

            // fix the current page
            page = buffer.getPage(pageNumber.getTreeId(), pageNumber);
            if (page == null)
                throw new ChaiDBException(ErrorCode.BTREE_INVALID_BTREEPAGE, "Page is null: " + pageNumber.toHexString() + " of " + btreeSpec.getBtreeName());
            if (Debug.DEBUG_CHECKPAGENUMBER) {
                if (!Debug.checkPageNumber(pageNumber, this.page)) {
                    logger.fatal(new Throwable("there is hole in GetPage!"));
                    this.buffer.dump();
                    Db.getLogManager().flush();
                    Debug.dumpPageToLog(page);
                    if (Debug.DEBUG_PAGEINFO_TRACE) Debug.pageHistory(this.pageNumber);
                    System.exit(-1);

                }
            }

            int currNode = getCurrNodeNumbers();
            // if page is root
            if (this.prevPage.getPageNumber() == 0 && currNode == 0) {
                //has only one child remaining, which should be the leftmost
                if (this.nextPage.getPageNumber() > 0) {
                    //Write lock child page
                    BTreePage child = new BTreePage(btreeSpec.btree.getBtreeId(), this.nextPage, btreeSpec, buffer);

                    // set the child to be root
                    /********* add by leon *******/
                    child.setLogInfo(txnId, needLog);
                    /***************************/
                    child.setPrevPage(new PageNumber(0));

                    result = new OperResult(true, child.pageNumber);
                    // unfix child
                    buffer.releasePage(child.pageNumber.getTreeId(), child.pageNumber, true);

                } else {
                    PageNumber p = new PageNumber(BTreeSpec.INVALID_PAGENO);
                    p.setTreeId(pageNumber.getTreeId());
                    result = new OperResult(true, p);
                }
                //free this root
                /******************* Add by Leon, Sep 30 *****************/
                if (needLog) {
                    int pgno = pageNumber.getPageNumber();
                    int prevPg = prevPage.getPageNumber();
                    int nextPg = nextPage.getPageNumber();

                    BTreeFreePageLogRecord lr = new BTreeFreePageLogRecord(pageNumber.getTreeId(), pgno, txnId, flags, prevPg, nextPg, keyType, -1, btreeSpec.btree.getType());
                    lr.log();
                }
                /***************************/
                buffer.addToFreeList(this.pageNumber.getTreeId(), this.pageNumber, needLog ? new Integer(txnId) : null); // delete the current page L

                // if the page has too few nodes and this is not the root page
            } else if (this.prevPage.getPageNumber() != 0 && currNode < order / 2) {
                BTreePage parent = new BTreePage(btreeSpec.btree.getBtreeId(), this.prevPage, btreeSpec, buffer);
                int nodeSize = btreeSpec.getInternalNodeSize();
                Key newKey = null; // V'
                BTreePage newPage = null; // L'

                // if this is the leftmost child in parent page
                // set L' to be the right sibling of the page
                if (parent.nextPage.getPageNumber() == this.pageNumber.getPageNumber()) {
                    // get L' and V'
                    BTreeNode newNode = parent.getNode(0);
                    /* Modified by ben zhang at Aug, 12, 2002*/
                    newKey = newNode.getKey();
                    newPage = new BTreePage(btreeSpec.btree.getBtreeId(), newNode.getPageNumber(), btreeSpec, buffer);
                    verifyLR(parent.pageNumber, pageNumber, newPage.pageNumber, true);

                    // if nodes in L and L' can fit in one page
                    int size = order;
                    if (!isLeaf() && isBTree()) size = order - 1;
                    if (currNode + newPage.getCurrNodeNumbers() <= size) {
                        if (isLeaf()) {
                            // append all nodes in L' to L
                            /********* add by leon *******/
                            if (needLog) {
                                int pgno = pageNumber.getPageNumber();
                                int siblingpgno = newPage.getPageNumber().getPageNumber();
                                BTreeMergeLogRecord lr = new BTreeMergeLogRecord(pageNumber.getTreeId(), pgno, txnId, false, siblingpgno, page, newPage.getPage(), (short) btreeSpec.getNodeSize(), btreeSpec.btree.getType());
                                lr.log();
                            }
                            /***************************/

                            for (int j = 0; j < newPage.getCurrNodeNumbers(); j++) {
                                upperBound -= nodeSize;
                                System.arraycopy(newPage.page, newPage.getNodeOffset(j), page, upperBound, nodeSize);
                                System.arraycopy(ByteTool.shortToBytes(upperBound), 0, page, lowerBound, 2);
                                lowerBound += 2;

                            }
                            setLowerBound(lowerBound);
                            setUpperBound(upperBound);

                            // set L.nextPage = L'.nextPage
                            setNextPage(newPage.nextPage);
                            // unfix this page L
                            buffer.releasePage(pageNumber.getTreeId(), pageNumber, true);
                        } else if (isBTree()) {
                            // append V' and leftmost pointer in L' to L
                            insertNode(newKey, ByteTool.intToBytes(newPage.nextPage.getPageNumber()), IDBIndex.STORE_REPLACE, kContext);
                            currNode = this.getCurrNodeNumbers();

                            // set newpage's child page's parent to this page
                            BTreePage childPage = new BTreePage(btreeSpec.btree.getBtreeId(), newPage.nextPage, btreeSpec, buffer);

                            /********* add by leon *******/
                            childPage.setLogInfo(txnId, needLog);
                            /***************************/
                            childPage.setPrevPage(pageNumber);
                            // unfix child page
                            buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
                            // fix this page

                            /********* add by leon *******/
                            if (needLog) {
                                int pgno = pageNumber.getPageNumber();
                                int siblingpgno = newPage.getPageNumber().getPageNumber();

                                BTreeMergeLogRecord lr = new BTreeMergeLogRecord(pageNumber.getTreeId(), pgno, txnId, false, siblingpgno, page, newPage.getPage(), (short) btreeSpec.getNodeSize(), btreeSpec.btree.getType());
                                lr.log();
                            }
                            /***************************/

                            // append all nodes in L' to L
                            for (int j = 0; j < newPage.getCurrNodeNumbers(); j++) {
                                upperBound -= nodeSize;
                                BTreeNode node = newPage.getNode(j);
                                // set newpage's child page's parent to this page
                                childPage = new BTreePage(btreeSpec.btree.getBtreeId(), node.getPageNumber(), btreeSpec, buffer);
                                /********* add by leon *******/
                                childPage.setLogInfo(txnId, needLog);
                                /***************************/
                                childPage.setPrevPage(pageNumber);
                                // unfix child page
                                buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
                                System.arraycopy(newPage.page, node.getNodeOffset(), page, upperBound, nodeSize);
                                System.arraycopy(ByteTool.shortToBytes(upperBound), 0, page, lowerBound, 2);
                                lowerBound += 2;
                            }
                            setLowerBound(lowerBound);
                            setUpperBound(upperBound);
                            // unfix this page
                            buffer.releasePage(pageNumber.getTreeId(), pageNumber, true);
                        }
                        if (Debug.DEBUG_BTREEPAGE) {
                            logger.debug("L: " + this.toString());
                            logger.debug("L': " + newPage.toString());
                        }
                        // delete L'
                        /******************* Add by Leon, Sep 30 *****************/
                        if (needLog) {
                            int pgno = newPage.pageNumber.getPageNumber();
                            int prevPg = newPage.prevPage.getPageNumber();
                            int nextPg = newPage.nextPage.getPageNumber();

                            BTreeFreePageLogRecord lr = new BTreeFreePageLogRecord(pageNumber.getTreeId(), pgno, txnId, newPage.flags, prevPg, nextPg, newPage.keyType, -1, btreeSpec.btree.getType());
                            lr.log();
                        }
                        /***************************/
                        buffer.addToFreeList(btreeSpec.btree.getBtreeId(), newPage.pageNumber, needLog ? new Integer(txnId) : null);

                        // recursive delete
                        result = parent.delete(newKey, kContext);

                    } else {

                        // redistribution: borrow one node from L' and insert to L rightmost
                        if (isLeaf()) {
                            BTreeNode firstNode = newPage.getNode(0);
                            int firstNodeOffset = firstNode.getNodeOffset();
                            // insert the new node to L rightmost
                            /***************** Add by leon,2001-9-27 14:56 ********************/
                            if (needLog) {
                                int pgno = pageNumber.getPageNumber();
                                byte[] oldV = ByteTool.shortToBytes(lowerBound);
                                oldV = ByteTool.append(oldV, ByteTool.shortToBytes(upperBound));
                                byte[] newV = ByteTool.shortToBytes((short) (lowerBound + 2));
                                newV = ByteTool.append(newV, ByteTool.shortToBytes((short) (upperBound - nodeSize)));
                                if (oldV != newV) {
                                    BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec.OFF_LOWERBOUND, oldV, newV, btreeSpec.btree.getType());
                                    lr.log();
                                }
                            }
                            /******************************************************************/
                            short oldLB = lowerBound;
                            setUpperBound((short) (upperBound - nodeSize));
                            setLowerBound((short) (lowerBound + 2));

                            /***************** Add by leon,2001-9-27 14:56 ********************/
                            if (needLog) {
                                int pgno = pageNumber.getPageNumber();
                                byte[] node = ByteTool.copyByteArray(newPage.page, firstNodeOffset, nodeSize);

                                BTreeAddRemoveLogRecord lr = new BTreeAddRemoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeAddRemoveLogRecord.ADD_FLAG, upperBound, node, btreeSpec.btree.getType());
                                lr.log();
                            }
                            /******************************************************************/
                            System.arraycopy(newPage.page, firstNodeOffset, page, upperBound, nodeSize);

                            /***************** Add by leon,2001-9-27 14:56 ********************/
                            if (needLog) {
                                int pgno = pageNumber.getPageNumber();
                                BTreeAddRemoveLogRecord lr = new BTreeAddRemoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeAddRemoveLogRecord.ADD_FLAG, oldLB, ByteTool.shortToBytes(upperBound), btreeSpec.btree.getType());
                                lr.log();
                            }
                            /******************************************************************/
                            System.arraycopy(ByteTool.shortToBytes(upperBound), 0, page, oldLB, 2);

                            // remove the first node from L'

                            /******************* Add by Leon, Sep 29 *****************/
                            int pgno = newPage.pageNumber.getPageNumber();
                            if (needLog) {
                                //remember the dead node
                                byte[] data = ByteTool.copyByteArray(newPage.page, firstNodeOffset, nodeSize);
                                BTreeAddRemoveLogRecord lr = new BTreeAddRemoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeAddRemoveLogRecord.REMOVE_FLAG, firstNodeOffset, data, btreeSpec.btree.getType());
                                lr.log();

                                //here we dont remember the offset of this node, for later move offset talbe will
                                //log it, which is different from borrowing the last node from left sibling.

                            }

                            if (firstNodeOffset != newPage.upperBound) {
                                if (needLog) {
                                    byte[] data = ByteTool.copyByteArray(newPage.page, newPage.upperBound, nodeSize);

                                    BTreeMoveLogRecord lr1 = new BTreeMoveLogRecord(pageNumber.getTreeId(), pgno, txnId, newPage.upperBound, firstNodeOffset, data.length, data, btreeSpec.btree.getType());
                                    lr1.log();
                                }
                                /***************************/
                                System.arraycopy(newPage.page, newPage.upperBound, newPage.page, firstNodeOffset, nodeSize);

                                // find the key has upperBound
                                int upperBoundNodeIndex = -1;
                                // some better algorithm later ###
                                for (int j = 0; j < newPage.getCurrNodeNumbers(); j++) {
                                    if (newPage.getNodeOffset(j) == newPage
                                            .upperBound) {
                                        upperBoundNodeIndex = j;
                                        break;
                                    }
                                }
                                if (upperBoundNodeIndex >= 0) {
                                    /***************** Add by leon,2001-9-27 14:56 ********************/
                                    if (needLog) {
                                        byte[] oldV = ByteTool.copyByteArray(newPage.page, BTreeSpec
                                                .PAGE_HEADER_SIZE + 2 * upperBoundNodeIndex, 2);
                                        byte[] newV = ByteTool.shortToBytes((short) firstNodeOffset);
                                        if (oldV != newV) {
                                            BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec
                                                    .PAGE_HEADER_SIZE + 2 * upperBoundNodeIndex, oldV, newV, btreeSpec.btree.getType());
                                            lr.log();
                                        }
                                    }
                                    /******************************************************************/
                                    System.arraycopy(ByteTool.shortToBytes((short) firstNodeOffset), 0, newPage.page, BTreeSpec
                                            .PAGE_HEADER_SIZE + 2 * upperBoundNodeIndex, 2);

                                }
                            }
                            // rest clean up, upperBound, lowerBound
                            oldLB = newPage.lowerBound;
                            /***************** Add by leon,2001-9-27 14:56 ********************/

                            if (needLog) {
                                byte[] oldV = ByteTool.shortToBytes(newPage.lowerBound);
                                oldV = ByteTool.append(oldV, ByteTool.shortToBytes(newPage.upperBound));
                                byte[] newV = ByteTool.shortToBytes((short) (newPage.lowerBound - 2));
                                newV = ByteTool.append(newV, ByteTool.shortToBytes((short) (newPage
                                        .upperBound + nodeSize)));
                                BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec.OFF_LOWERBOUND, oldV, newV, btreeSpec.btree.getType());
                                lr.log();
                            }
                            /******************************************************************/
                            newPage.setUpperBound((short) (newPage.upperBound + nodeSize));
                            newPage.setLowerBound((short) (newPage.lowerBound - 2));
                            // move all pointers one slot up

                            /******************* Add by Leon, Sep 29 *****************/
                            if (needLog) {
                                byte[] data = ByteTool.copyByteArray(newPage.page, BTreeSpec.PAGE_HEADER_SIZE, 2);

                                BTreeAddRemoveLogRecord lr = new BTreeAddRemoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeAddRemoveLogRecord.REMOVE_FLAG, BTreeSpec.PAGE_HEADER_SIZE, data, btreeSpec.btree.getType());

                                lr.log();

                                data = ByteTool.copyByteArray(newPage.page, BTreeSpec.PAGE_HEADER_SIZE + 2, oldLB - BTreeSpec.PAGE_HEADER_SIZE - 2);

                                BTreeMoveLogRecord lr1 = new BTreeMoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec.PAGE_HEADER_SIZE + 2, BTreeSpec.PAGE_HEADER_SIZE, data.length, data, btreeSpec.btree.getType());
                                lr1.log();
                            }
                            /***************************/
                            System.arraycopy(newPage.page, BTreeSpec.PAGE_HEADER_SIZE + 2, newPage.page, BTreeSpec.PAGE_HEADER_SIZE, oldLB - BTreeSpec.PAGE_HEADER_SIZE - 2);

                            // replace V' in parent by firstNode's key
                            BTreeNode newFirstNode = newPage.getNode(0);
                            newNode.internalReplaceKey(newFirstNode.getKey().toBytes(), kContext);
                        } else if (isBTree()) {
                            PageNumber leftmostPageNumber = new PageNumber(newPage.nextPage);
                            BTreeNode firstNode = newPage.getNode(0);
                            PageNumber firstNodePageNumber = firstNode.getPageNumber();
                            /*Modified by ben zhang at Aug, 12, 2002 */
                            Key firstNodeKey = firstNode.getKey();
                            // remove the first node from L', already unfix page

                            /********* add by leon *******/
                            newPage.setLogInfo(txnId, needLog);
                            /***************************/
                            newPage.setNextPage(firstNodePageNumber);

                            newPage.deleteNode(firstNodeKey, kContext);
                            // insert V' and leftmostPageNumber to the rightmost of L
                            // already unfix page
                            insertNode(newKey, ByteTool.intToBytes(leftmostPageNumber.getPageNumber()), IDBIndex.STORE_REPLACE, kContext);

                            // set newpage's child page's parent to this page
                            BTreePage childPage = new BTreePage(btreeSpec.btree.getBtreeId(), leftmostPageNumber, btreeSpec, buffer);

                            /********* add by leon *******/
                            childPage.setLogInfo(txnId, needLog);
                            /***************************/
                            childPage.setPrevPage(pageNumber);

                            // unfix child page
                            buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
                            // replace V' in parent by firstNode's key
                            newNode.internalReplaceKey(firstNodeKey.toBytes(), kContext);

                        }

                        // unfix and unlock this page and its sibling
                        buffer.releasePage(pageNumber.getTreeId(), pageNumber, true);
                        buffer.releasePage(newPage.pageNumber.getTreeId(), newPage.pageNumber, true);
                        result = new OperResult(true, null);
                    }

                    // otherwise let L' be the left sibling (predecessor) of this page L
                } else {
                    // get L' and V'
                    int prevIndex = parent.nextPage.getPageNumber();
                    BTreeNode newNode = null;
//                    int newNodeLocation = 0;

                    for (int i = 0; i < parent.getCurrNodeNumbers(); i++) {
                        BTreeNode node = parent.getNode(i);
                        if (node.getPageNumber().getPageNumber() == this.pageNumber.getPageNumber()) {
                            /* Modified by ben at Aug, 12, 2002 */
                            newKey = node.getKey();
                            newNode = node;
//                            newNodeLocation = i;
                            break;
                        }
                        prevIndex = node.getPageNumber().getPageNumber();
                    }

                    tmpPgNo = new PageNumber(prevIndex);
                    tmpPgNo.setTreeId(btreeSpec.btree.getBtreeId());
                    newPage = new BTreePage(btreeSpec.btree.getBtreeId(), tmpPgNo, btreeSpec, buffer);

                    verifyLR(parent.pageNumber, newPage.pageNumber, pageNumber, false);

                    if (Debug.DEBUG_BTREEPAGE)
                        logger.debug("L'= " + newPage.pageNumber.getPageNumber() + " V'=" + new String(newKey.toBytes())); //Modified by ben at Aug, 12, 2002. Pending issue

                    // if nodes in L and L' can fit in one page
                    int size = order;
                    if (!isLeaf() && isBTree()) size = order - 1;
                    if (currNode + newPage.getCurrNodeNumbers() <= size) {
                        if (isLeaf()) {
                            /********* add by leon *******/
                            if (needLog) {
                                int pgno = pageNumber.getPageNumber();
                                int siblingpgno = newPage.getPageNumber().getPageNumber();

                                BTreeMergeLogRecord lr = new BTreeMergeLogRecord(pageNumber.getTreeId(), pgno, txnId, true, siblingpgno, page, newPage.getPage(), (short) btreeSpec.getNodeSize(), btreeSpec.btree.getType());
                                lr.log();
                            }
                            /***************************/
                            // append all nodes in L to L'
                            for (int j = 0; j < currNode; j++) {
                                newPage.upperBound -= nodeSize;
                                System.arraycopy(page, getNodeOffset(j), newPage.page, newPage.upperBound, nodeSize);
                                System.arraycopy(ByteTool.shortToBytes(newPage.upperBound), 0, newPage.page, newPage.lowerBound, 2);
                                newPage.lowerBound += 2;

                            }
                            newPage.setLowerBound(newPage.lowerBound);
                            newPage.setUpperBound(newPage.upperBound);
                            // set L'.nextPage = L.nextPage

                            /********* add by leon *******/
                            newPage.setLogInfo(txnId, needLog);
                            /***************************/
                            newPage.setNextPage(this.nextPage);

                            // unfix new page
                            buffer.releasePage(newPage.pageNumber.getTreeId(), newPage.pageNumber, true);
                        } else if (isBTree()) {
                            // append V' and leftmost pointer in L to L'
                            newPage.insertNode(newKey, ByteTool.intToBytes(this.nextPage.getPageNumber()), IDBIndex.STORE_REPLACE, kContext);

                            // set child page's parent to newPage
                            BTreePage childPage = new BTreePage(btreeSpec.btree.getBtreeId(), this.nextPage, btreeSpec, buffer);
                            /********* add by leon *******/
                            childPage.setLogInfo(txnId, needLog);
                            /***************************/
                            childPage.setPrevPage(newPage.pageNumber);
                            // unfix child page
                            buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
                            // fix new page
                            //newPage.page = buffer.getPage(btreeSpec.btree.getBtreeId(),newPage.pageNumber);

                            /********* add by leon *******/
                            if (needLog) {
                                int pgno = pageNumber.getPageNumber();
                                int siblingpgno = newPage.getPageNumber().getPageNumber();

                                BTreeMergeLogRecord lr = new BTreeMergeLogRecord(pageNumber.getTreeId(), pgno, txnId, true, siblingpgno, page, newPage.getPage(), (short) btreeSpec.getNodeSize(), btreeSpec.btree.getType());
                                lr.log();
                            }
                            /***************************/
                            // append all nodes in L to L'
                            for (int j = 0; j < currNode; j++) {
                                newPage.upperBound -= nodeSize;
                                BTreeNode node = getNode(j);
                                // set child page's parent to new page
                                childPage = new BTreePage(btreeSpec.btree.getBtreeId(), node.getPageNumber(), btreeSpec, buffer);

                                /********* add by leon *******/
                                childPage.setLogInfo(txnId, needLog);
                                /***************************/
                                childPage.setPrevPage(newPage.pageNumber);
                                // unfix child page
                                buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
                                System.arraycopy(page, getNodeOffset(j), newPage.page, newPage.upperBound, nodeSize);
                                System.arraycopy(ByteTool.shortToBytes(newPage.upperBound), 0, newPage.page, newPage.lowerBound, 2);
                                newPage.lowerBound += 2;

                            }
                            newPage.setLowerBound(newPage.lowerBound);
                            newPage.setUpperBound(newPage.upperBound);
                            // unfix new page
                            buffer.releasePage(newPage.pageNumber.getTreeId(), newPage.pageNumber, true);
                        }
                        if (Debug.DEBUG_BTREEPAGE) {
                            logger.debug("L: " + this.toString());
                            logger.debug("L': " + newPage.toString());
                        }

                        // delete L
                        /******************* Add by Leon, Sep 30 *****************/
                        if (needLog) {
                            int pgno = pageNumber.getPageNumber();
                            int prevPg = prevPage.getPageNumber();
                            int nextPg = nextPage.getPageNumber();

                            BTreeFreePageLogRecord lr = new BTreeFreePageLogRecord(pageNumber.getTreeId(), pgno, txnId, flags, prevPg, nextPg, keyType, -1, btreeSpec.btree.getType());
                            lr.log();
                        }
                        /***************************/
                        buffer.addToFreeList(btreeSpec.btree.getBtreeId(), this.pageNumber, needLog ? new Integer(txnId) : null);

                        // delete node from parent
                        result = parent.delete(newKey, kContext);

                    } else {

                        // redistribution: borrow and node from L' and insert to L leftmost
                        if (isLeaf()) {
                            BTreeNode lastNode = newPage.getNode(newPage.getCurrNodeNumbers() - 1);
                            byte[] lastNodeKey = lastNode.getKey().toBytes();
                            int lastNodeOffset = lastNode.getNodeOffset();
                            // insert to the new node to L leftmost
                            /***************** Add by leon,2001-9-27 14:56 ********************/

                            if (needLog) {
                                int pgno = pageNumber.getPageNumber();
                                byte[] oldV = ByteTool.shortToBytes(lowerBound);
                                oldV = ByteTool.append(oldV, ByteTool.shortToBytes(upperBound));
                                byte[] newV = ByteTool.shortToBytes((short) (lowerBound + 2));
                                newV = ByteTool.append(newV, ByteTool.shortToBytes((short) (upperBound - nodeSize)));
                                BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec.OFF_LOWERBOUND, oldV, newV, btreeSpec.btree.getType());
                                lr.log();
                            }
                            /******************************************************************/
                            setLowerBound((short) (lowerBound + 2));
                            setUpperBound((short) (upperBound - nodeSize));
                            /***************** Add by leon,2001-9-27 14:56 ********************/
                            if (needLog) {
                                int pgno = pageNumber.getPageNumber();
                                byte[] node = ByteTool.copyByteArray(newPage.page, lastNodeOffset, nodeSize);

                                BTreeAddRemoveLogRecord lr = new BTreeAddRemoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeAddRemoveLogRecord.ADD_FLAG, upperBound, node, btreeSpec.btree.getType());
                                lr.log();
                            }
                            /******************************************************************/
                            System.arraycopy(newPage.page, lastNodeOffset, page, upperBound, nodeSize);

                            /******************* Add by Leon, Sep 29 *****************/

                            if (needLog) {
                                int pgno = pageNumber.getPageNumber();
                                byte[] oldV = ByteTool.copyByteArray(page, BTreeSpec.PAGE_HEADER_SIZE, 2 * currNode);
                                byte[] newV = ByteTool.shortToBytes(upperBound);
                                newV = ByteTool.append(newV, oldV);
                                BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec.PAGE_HEADER_SIZE, oldV, newV, btreeSpec.btree.getType());
                                lr.log();
                            }
                            /***************************/
                            System.arraycopy(page, BTreeSpec.PAGE_HEADER_SIZE, page, BTreeSpec.PAGE_HEADER_SIZE + 2, 2 * currNode);
                            System.arraycopy(ByteTool.shortToBytes(upperBound), 0, page, BTreeSpec.PAGE_HEADER_SIZE, 2);

                            // remove the last node from L'

                            /******************* Add by Leon, Sep 29 *****************/
                            int pgno = newPage.pageNumber.getPageNumber();
                            if (needLog) {
                                //remember the dead node.
                                byte[] data = ByteTool.copyByteArray(newPage.page, lastNodeOffset, nodeSize);
                                BTreeAddRemoveLogRecord lr = new BTreeAddRemoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeAddRemoveLogRecord.REMOVE_FLAG, lastNodeOffset, data, btreeSpec.btree.getType());
                                lr.log();

                                data = ByteTool.copyByteArray(newPage.page, newPage.lowerBound - 2, 2);
                                lr = new BTreeAddRemoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeAddRemoveLogRecord.REMOVE_FLAG, newPage.lowerBound - 2, data, btreeSpec.btree.getType());
                                lr.log();

                            }

                            if (lastNodeOffset != newPage.upperBound) {
                                if (needLog) {
                                    byte[] data = ByteTool.copyByteArray(newPage.page, newPage.upperBound, nodeSize);

                                    BTreeMoveLogRecord lr1 = new BTreeMoveLogRecord(pageNumber.getTreeId(), pgno, txnId, newPage.upperBound, lastNodeOffset, data.length, data, btreeSpec.btree.getType());
                                    lr1.log();
                                }
                                /***************************/
                                System.arraycopy(newPage.page, newPage.upperBound, newPage.page, lastNodeOffset, nodeSize);

                                // find the key has upperBound
                                int upperBoundNodeIndex = -1;
                                // some better algorithm later ###
                                for (int j = 0; j < newPage.getCurrNodeNumbers(); j++) {
                                    if (newPage.getNodeOffset(j) == newPage
                                            .upperBound) {
                                        upperBoundNodeIndex = j;
                                        break;
                                    }
                                }
                                if (upperBoundNodeIndex >= 0) {
                                    /****** Add by leon,2001-9-27 14:56 ******/

                                    if (needLog) {
                                        byte[] oldV = ByteTool.copyByteArray(newPage.page, BTreeSpec
                                                .PAGE_HEADER_SIZE + 2 * upperBoundNodeIndex, 2);
                                        byte[] newV = ByteTool.shortToBytes((short) lastNodeOffset);
                                        BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec
                                                .PAGE_HEADER_SIZE + 2 * upperBoundNodeIndex, oldV, newV, btreeSpec.btree.getType());
                                        lr.log();
                                    }
                                    /******************************************************************/
                                    System.arraycopy(ByteTool.shortToBytes((short) lastNodeOffset), 0, newPage.page, BTreeSpec
                                            .PAGE_HEADER_SIZE + 2 * upperBoundNodeIndex, 2);

                                }
                            }
                            // rest clean up, upperBound, lowerBound

                            /******************* Add by Leon, Sep 29 *****************/

                            if (needLog) {
                                byte[] oldV = ByteTool.copyByteArray(newPage.page, BTreeSpec.OFF_LOWERBOUND, 4);
                                byte[] newV = ByteTool.shortToBytes((short) (newPage.lowerBound - 2));
                                newV = ByteTool.append(newV, ByteTool.shortToBytes((short) (newPage
                                        .upperBound + nodeSize)));
                                BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec.OFF_LOWERBOUND, oldV, newV, btreeSpec.btree.getType());
                                lr.log();
                            }
                            /***************************/
                            newPage.setUpperBound((short) (newPage.upperBound + nodeSize));
                            newPage.setLowerBound((short) (newPage.lowerBound - 2));

                            if (newPage.getCurrNodeNumbers() == 0) {
                                /******************* Add by Leon, Sep 30 *****************/
                                if (needLog) {
                                    int prevPg = newPage.prevPage.getPageNumber();
                                    int nextPg = newPage.nextPage.getPageNumber();

                                    BTreeFreePageLogRecord lr = new BTreeFreePageLogRecord(pageNumber.getTreeId(), pgno, txnId, newPage.flags, prevPg, nextPg, newPage.keyType, -1, btreeSpec.btree.getType());
                                    lr.log();
                                }
                                /***************************/
                                buffer.addToFreeList(btreeSpec.btree.getBtreeId(), newPage.pageNumber, needLog ? new Integer(txnId) : null);
                            }

                            // replace V' in parent by lastNode's key
                            newNode.internalReplaceKey(lastNodeKey, kContext);

                        } else if (isBTree()) {
                            BTreeNode lastNode = newPage.getNode(newPage.getCurrNodeNumbers() - 1);
                            PageNumber lastNodePageNumber = lastNode.getPageNumber();
                            /* Modified by ben zhang at Aug, 12, 2002 */
                            Key lastNodeKey = lastNode.getKey();
                            // set child page's parent to this page
                            BTreePage childPage = new BTreePage(btreeSpec.btree.getBtreeId(), lastNodePageNumber, btreeSpec, buffer);

                            /********* add by leon *******/
                            childPage.setLogInfo(txnId, needLog);
                            /***************************/
                            childPage.setPrevPage(pageNumber);
                            // unfix child page
                            buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
                            PageNumber oldNextPage = new PageNumber(nextPage);
                            setNextPage(lastNodePageNumber);
                            // insert lastNodePageNumber and V' to L; already unfix page
                            insertNode(newKey, ByteTool.intToBytes(oldNextPage.getPageNumber()), IDBIndex.STORE_REPLACE, kContext);
                            // remove the last node from L'; already unfix page
                            newPage.deleteNode(lastNodeKey, kContext);
                            // replace V' in parent by lastNode's key
                            newNode.internalReplaceKey(lastNodeKey.toBytes(), kContext);

View Full Code Here

Examples of org.chaidb.db.index.btree.bufmgr.PageNumber

    public PageNumber getPageNumber() {
        return pageNumber;
    }

    void setPageNumber(int _pageNumber) {
        this.pageNumber = new PageNumber(_pageNumber);
    }
View Full Code Here
TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.