Package org.chaidb.db.index.btree.bufmgr

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


                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

            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

        // 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

        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

        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

                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

     */
    //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

    public PageNumber getPageNumber() {
        return pageNumber;
    }

    void setPageNumber(int _pageNumber) {
        this.pageNumber = new PageNumber(_pageNumber);
    }
View Full Code Here

        /* to prevent OOM */
        if (keySize > MAX_KEY_SIZE || keySize < MIN_KEY_SIZE) {
            throw new ChaiDBException(ErrorCode.BTREE_INVALID_BTREEPAGE, "keysize is out of bound:" + keySize);
        }

        pageNumber = new PageNumber(ByteTool.bytesToInt(rawPage, nodeOffset + BTreeSpec.NODE_OFF_PAGENUMBER, this.page.btreeSpec.isMsbFirst()));
        pageNumber.setTreeId(page.btreeSpec.btree.getBtreeId());

        flags = rawPage[nodeOffset + BTreeSpec.NODE_OFF_FLAGS];
        if (flags < 0 || flags > 3) {
            throw new ChaiDBException(ErrorCode.BTREE_INVALID_BTREEPAGE, "flags is out of bound:" + flags);
View Full Code Here

TOP

Related Classes of org.chaidb.db.index.btree.bufmgr.PageNumber

Copyright © 2018 www.massapicom. 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.