示例#1
0
/**
 * Index lookup for a key. Returns the rid if found, else -1.
 * Assuming the index on a candidate key.
 */
int BPlusTree::lookUp(int key) {
    BufferManager *bm = BufferManager::getInstance(dbName);

    int height = 0;
    //TreeNode **trace = (TreeNode **)malloc(10);
    TreeNode **trace = new TreeNode *[10];
    for (int i = 0; i < 10; i++)
        trace[i] = NULL;

    TreeNode *leafNode = getLeaf(key, trace, &height);
    int nofPairs = leafNode->getNoPairs();
    int ithKey = readInt(leafNode->getBuffPage(),
            2 * SIZE_INT + PTR_SIZE);
    int keyCount;
    int rid;
    cout << nofPairs << endl;
    for (keyCount = 0; keyCount < nofPairs && key > ithKey; keyCount++) {

        //cout<<"in lookup for insert ithkey "<<ithKey<<endl;
        ithKey = readInt(leafNode->getBuffPage(),
                2 * SIZE_INT + (keyCount + 1) * PAIR_SIZE + PTR_SIZE);
        //cout<<"loop "<<keyCount<<endl;
    }
    rid = readInt(leafNode->getBuffPage(),
            2 * SIZE_INT + (keyCount) * PAIR_SIZE);
    cout << "key " << key << "rid " << rid << endl;
    //unpin the trace 
    for (int level = 1; trace[level] != NULL; level++) {
        bm->unpinPage(trace[level]->getBuffPage(), false);
        delete trace[level];
    }
    free(trace);
    if (nofPairs == 0)
        return -1;


    if (key == ithKey && keyCount < nofPairs)
        return rid;
    else
        return -1;
}
示例#2
0
void BPlusTree::recursiveDeleteEntry(TreeNode *node, int key,
        int pointer, TreeNode** trace, int level) {

    BufferManager *bm = BufferManager::getInstance(dbName);
    int noPairsInNode = node->getNoPairs();
    int node_diskBlockId;
    int keyCount;
    int ithKey;

    if (node->isLeaf()) {

        cout << "delete key: " << key <<
                " pointer: " << pointer << " in leaf" << endl;

        ithKey = readInt(node->getBuffPage(), 2 * SIZE_INT + PTR_SIZE);
        for (keyCount = 0; keyCount < noPairsInNode &&
                key != ithKey; keyCount++) {

            ithKey = readInt(node->getBuffPage(),
                    2 * SIZE_INT + (keyCount + 1) * PAIR_SIZE + PTR_SIZE);
        }

        moveBytes(node->getBuffPage() +
                2 * SIZE_INT + (keyCount + 1) * PAIR_SIZE,
                node->getBuffPage() +
                2 * SIZE_INT + keyCount*PAIR_SIZE,
                (noPairsInNode - keyCount - 1) * PAIR_SIZE);

        node->setNoPairs(noPairsInNode - 1);
    } else {

        cout << "delete key: " << key <<
                " pointer: " << pointer << " in non leaf" << endl;

        ithKey = readInt(node->getBuffPage(), 2 * SIZE_INT + PTR_SIZE);

        for (keyCount = 0; keyCount < noPairsInNode &&
                key != ithKey; keyCount++) {

            //cout<<"ithKey "<<ithKey<<endl;
            ithKey = readInt(node->getBuffPage(),
                    2 * SIZE_INT + (keyCount + 1) * PAIR_SIZE + PTR_SIZE);
        }

        moveBytes(node->getBuffPage() + 2 * SIZE_INT +
                (keyCount + 1) * PAIR_SIZE + PTR_SIZE,
                node->getBuffPage() + 2 * SIZE_INT +
                keyCount * PAIR_SIZE + PTR_SIZE,
                (noPairsInNode - keyCount - 1) * PAIR_SIZE);

        node->setNoPairs(noPairsInNode - 1);
    }

    noPairsInNode = node->getNoPairs();
    //node is root and only one pointer in it after deletion
    if (level == 0) {
        //root is not a leaf
        if (node->isLeaf() == 0 && noPairsInNode == 0) {

            cout << "root is not a leaf(termination condition)" << endl;
            int rootChildId = readInt(node->getBuffPage(), 2 * SIZE_INT);
            TreeNode *rootChildNode =
                    new TreeNode(bm->pinPage(rootChildId));

            moveBytes(rootChildNode->getBuffPage(),
                    node->getBuffPage(),
                    BLOCK_SIZE);

            bm->unpinPage(rootChildId, false);
            StorageManager::freeBlock(dbName, rootChildId);
        }
        cout << "terminates" << endl;
        //no unpin needed here
    } else if (noPairsInNode < (maxNoPairs + 1) / 2 && level != 0) {

        TreeNode *parentNode = trace[level - 1];
        int noPairsInParent = parentNode->getNoPairs();
        int kDash;

        int searchKey = readInt(node->getBuffPage(),
                2 * SIZE_INT + PTR_SIZE);

        ithKey = readInt(parentNode->getBuffPage(),
                2 * SIZE_INT + PTR_SIZE);

        for (keyCount = 0; keyCount < noPairsInParent &&
                searchKey >= ithKey; keyCount++) {

            ithKey = readInt(parentNode->getBuffPage(),
                    2 * SIZE_INT + (keyCount + 1) * PAIR_SIZE + PTR_SIZE);
        }

        TreeNode *siblingNode;
        int siblingNodeId;
        int swapCheck = 0;
        int noPairsInSibling;
        int nodeToBeDeleted;

        //finding N'
        /**
         * sibling is the leftmost node wherein swapping 
         * the pointers N and N' is needed
         */
        if (keyCount == 0) {
            //sibling to unpined using siblingNodeId
            node_diskBlockId = readInt(parentNode->getBuffPage(),
                    2 * SIZE_INT);

            siblingNodeId = readInt(parentNode->getBuffPage(),
                    2 * SIZE_INT + PAIR_SIZE);

            siblingNode = new TreeNode(bm->pinPage(siblingNodeId));
            kDash = ithKey;
            swapCheck = 1;
            nodeToBeDeleted = siblingNodeId;
        }            /**
		  * sibling is not thethe leftmost node 
		  */
        else {
            node_diskBlockId = readInt(parentNode->getBuffPage(),
                    2 * SIZE_INT + keyCount * PAIR_SIZE);

            siblingNodeId = readInt(parentNode->getBuffPage(),
                    2 * SIZE_INT + (keyCount - 1) * PAIR_SIZE);

            siblingNode = new TreeNode(bm->pinPage(siblingNodeId));
            kDash = readInt(parentNode->getBuffPage(),
                    2 * SIZE_INT + (keyCount - 1) *
                    PAIR_SIZE + PTR_SIZE);

            nodeToBeDeleted = readInt(parentNode->getBuffPage(),
                    2 * SIZE_INT + (keyCount) * PAIR_SIZE);
        }
        noPairsInSibling = siblingNode->getNoPairs();


        int mergeCheck = 0;
        if (node->isLeaf()) {

            if (node->getNoPairs() + noPairsInSibling <= maxNoPairs) {

                mergeCheck = 1;
            }

        } else {

            if (node->getNoPairs() + noPairsInSibling +
                    1 <= maxNoPairs) {

                mergeCheck = 1;
            }

        }

        if (mergeCheck == 1) {
            cout << "merging case" << endl;
            /**
             * swaping the names of the node , sibling we always make
             * sure that we dump(or merge ) the content of 
             * left node into right node ,but the siblingNodeId is 
             * same(new treenode which is not in trace)  		
             */
            if (swapCheck == 1) {
                TreeNode *temp;
                temp = node;
                node = siblingNode;
                siblingNode = temp;
            }

            if (node->isLeaf()) {
                noPairsInNode = node->getNoPairs();
                noPairsInSibling = siblingNode->getNoPairs();

                moveBytes(node->getBuffPage() + 2 * SIZE_INT,
                        siblingNode->getBuffPage() +
                        2 * SIZE_INT + (noPairsInSibling) * PAIR_SIZE,
                        noPairsInNode * PAIR_SIZE);

                moveBytes(node->getBuffPage() + BLOCK_SIZE - PTR_SIZE,
                        siblingNode->getBuffPage() + BLOCK_SIZE - PTR_SIZE,
                        PTR_SIZE);

                siblingNode->setNoPairs(noPairsInSibling +
                        noPairsInNode);
            } else {
                noPairsInNode = node->getNoPairs();
                noPairsInSibling = siblingNode->getNoPairs();

                writeInt(siblingNode->getBuffPage(),
                        2 * SIZE_INT + noPairsInSibling *
                        PAIR_SIZE + PTR_SIZE,
                        kDash);

                moveBytes(node->getBuffPage() + 2 * SIZE_INT,
                        siblingNode->getBuffPage() + 2 * SIZE_INT +
                        (noPairsInSibling + 1) * PAIR_SIZE,
                        noPairsInNode * PAIR_SIZE + PTR_SIZE);

                siblingNode->setNoPairs(noPairsInSibling +
                        noPairsInNode + 1);
            }

            if (swapCheck == 1) {

                bm->unpinPage(trace[level]->getBuffPage(), true);
                bm->unpinPage(siblingNodeId, false);
                StorageManager::freeBlock(dbName, siblingNodeId);
                delete trace[level];
            } else {

                bm->unpinPage(trace[level]->getBuffPage(), false);
                bm->unpinPage(siblingNodeId, true);
                StorageManager::freeBlock(dbName, node_diskBlockId);
                delete trace[level];
            }

            cout << "kDash: " << kDash << endl;
            recursiveDeleteEntry(parentNode, kDash,
                    nodeToBeDeleted, trace, level - 1);
        }            //redistribution 
        else {
            cout << "redistribution ";
            //if N' is predecessor of N
            if (swapCheck != 1) {

                if (node->isLeaf()) {

                    cout << " leaf,middle node" << endl;
                    int lastKeyInSibling = readInt(
                            siblingNode->getBuffPage(),
                            2 * SIZE_INT + noPairsInSibling *
                            PAIR_SIZE - PTR_SIZE);

                    int lastRidInSibling = readInt(
                            siblingNode->getBuffPage(),
                            2 * SIZE_INT + (noPairsInSibling - 1) *
                            PAIR_SIZE);

                    moveBytes(node->getBuffPage() + 2 * SIZE_INT,
                            node->getBuffPage() +
                            2 * SIZE_INT + PAIR_SIZE,
                            noPairsInNode * PAIR_SIZE);

                    siblingNode->setNoPairs(noPairsInSibling - 1);
                    noPairsInSibling = siblingNode->getNoPairs();

                    writeInt(node->getBuffPage(), 2 * SIZE_INT,
                            lastRidInSibling);

                    writeInt(node->getBuffPage(),
                            2 * SIZE_INT + PTR_SIZE, lastKeyInSibling);

                    node->setNoPairs(noPairsInNode + 1);

                    //node is not the first child of parent node 			
                    writeInt(parentNode->getBuffPage(),
                            2 * SIZE_INT + (keyCount - 1) * PAIR_SIZE +
                            PTR_SIZE, lastKeyInSibling);


                } else {
                    cout << "      non leaf,middle node" << endl;
                    int lastKeyInSibling = readInt(
                            siblingNode->getBuffPage(), 2 * SIZE_INT +
                            noPairsInSibling * PAIR_SIZE - PTR_SIZE);

                    int lastPtrInSibling = readInt(
                            siblingNode->getBuffPage(), 2 * SIZE_INT +
                            noPairsInSibling * PAIR_SIZE);

                    moveBytes(node->getBuffPage() + 2 * SIZE_INT,
                            node->getBuffPage() + 2 * SIZE_INT +
                            PAIR_SIZE, noPairsInNode *
                            PAIR_SIZE + PTR_SIZE);

                    siblingNode->setNoPairs(noPairsInSibling - 1);
                    noPairsInSibling = siblingNode->getNoPairs();

                    writeInt(node->getBuffPage(), 2 * SIZE_INT,
                            lastPtrInSibling);

                    writeInt(node->getBuffPage(), 2 * SIZE_INT +
                            PTR_SIZE, kDash);

                    node->setNoPairs(noPairsInNode + 1);

                    writeInt(parentNode->getBuffPage(), 2 * SIZE_INT +
                            (keyCount - 1) * PAIR_SIZE + PTR_SIZE,
                            lastKeyInSibling);

                }
            } else {
                if (node->isLeaf()) {
                    cout << "    leaf,leftmost node" << endl;
                    int firstRidInSibling = readInt(
                            siblingNode->getBuffPage(), 2 * SIZE_INT);

                    int firstKeyInSibling = readInt(
                            siblingNode->getBuffPage(),
                            2 * SIZE_INT + PTR_SIZE);

                    moveBytes(siblingNode->getBuffPage() +
                            2 * SIZE_INT + PAIR_SIZE,
                            siblingNode->getBuffPage() + 2 * SIZE_INT,
                            (noPairsInSibling - 1) * PAIR_SIZE);

                    siblingNode->setNoPairs(noPairsInSibling - 1);
                    noPairsInSibling = siblingNode->getNoPairs();

                    writeInt(node->getBuffPage(), 2 * SIZE_INT +
                            noPairsInNode*PAIR_SIZE, firstRidInSibling);

                    writeInt(node->getBuffPage(), 2 * SIZE_INT +
                            noPairsInNode * PAIR_SIZE + PTR_SIZE,
                            firstKeyInSibling);

                    node->setNoPairs(noPairsInNode + 1);


                    //node is first child of parent node 					
                    firstKeyInSibling = readInt(
                            siblingNode->getBuffPage(),
                            2 * SIZE_INT + PTR_SIZE);

                    writeInt(parentNode->getBuffPage(),
                            2 * SIZE_INT + PTR_SIZE,
                            firstKeyInSibling);

                } else {
                    cout << "      non leaf,leftmost node" << endl;
                    int firstPtrInSibling = readInt(
                            siblingNode->getBuffPage(), 2 * SIZE_INT);

                    int firstKeyInSibling = readInt(
                            siblingNode->getBuffPage(),
                            2 * SIZE_INT + PTR_SIZE);

                    moveBytes(siblingNode->getBuffPage() +
                            2 * SIZE_INT + PAIR_SIZE,
                            siblingNode->getBuffPage() + 2 * SIZE_INT,
                            (noPairsInSibling - 1) * PAIR_SIZE +
                            PTR_SIZE);


                    siblingNode->setNoPairs(noPairsInSibling - 1);
                    noPairsInSibling = siblingNode->getNoPairs();

                    writeInt(node->getBuffPage(), 2 * SIZE_INT +
                            noPairsInNode * PAIR_SIZE +
                            PTR_SIZE, kDash);

                    writeInt(node->getBuffPage(), 2 * SIZE_INT +
                            (noPairsInNode + 1) * PAIR_SIZE,
                            firstPtrInSibling);

                    node->setNoPairs(noPairsInNode + 1);

                    writeInt(parentNode->getBuffPage(),
                            2 * SIZE_INT + PTR_SIZE,
                            firstKeyInSibling);

                }
            }

            bm->unpinPage(trace[level]->getBuffPage(), true);
            bm->unpinPage(siblingNodeId, true);
            delete trace[level];
            for (int i = level - 1; i >= 1; i--) {
                bm->unpinPage(trace[i]->getBuffPage(), false);
                delete trace[i];
            }

        }
    }
    cout << key << "key deleted at level " << level << endl << endl;
}
示例#3
0
void BPlusTree::insertInParent(TreeNode *node,
        int startKeyInSplitNode,
        int splitNodeId,
        TreeNode** trace, int level) {

    BufferManager *bm = BufferManager::getInstance(dbName);
    //cout<<endl<<"level: "<<level<<"startKeyInSplitNode: "<<startKeyInSplitNode<<endl;
    if (level == 0) {
        //cout<<"parent is root"<<endl;
        int newId = StorageManager::allocateBlock(dbName);
        char* newNodeBuff = bm->pinPage(newId);
        TreeNode *newNode = new TreeNode(newNodeBuff);

        //copying the content of old root to new node
        moveBytes(root->getBuffPage(), newNode->getBuffPage(),
                BLOCK_SIZE);

        root->setNoPairs(1);
        root->setIsLeaf(0);

        writeInt(root->getBuffPage(), 2 * SIZE_INT, newId);

        writeInt(root->getBuffPage(),
                2 * SIZE_INT + PTR_SIZE, startKeyInSplitNode);

        writeInt(root->getBuffPage(),
                2 * SIZE_INT + PAIR_SIZE, splitNodeId);

        bm->unpinPage(newId, true);
        delete newNode;
        cout << "parent is root: done" << endl;
    } else {
        //cout<<"else case entered"<<endl;
        TreeNode *parentNode = trace[level - 1];
        int noPairs = parentNode->getNoPairs();
        cout << "no of pairs" << noPairs << endl;
        if (noPairs < maxNoPairs) {
            //int childId = getDiskBlockId( node->getBuffPage() );
            int firstKeyInNode = readInt(node->getBuffPage(),
                    2 * SIZE_INT + PTR_SIZE);

            int keyCount;
            int ithKey = readInt(parentNode->getBuffPage(),
                    2 * SIZE_INT + PTR_SIZE);

            for (keyCount = 0; keyCount < noPairs &&
                    firstKeyInNode >= ithKey; keyCount++) {

                ithKey = readInt(parentNode->getBuffPage(),
                        2 * SIZE_INT + (keyCount + 1) * PAIR_SIZE + PTR_SIZE);
            }

            cout << " keycount: " << keyCount << " stop Key " << ithKey << endl;

            if (keyCount < noPairs) {

                moveBytes(parentNode->getBuffPage() + 2 * SIZE_INT +
                        keyCount * PAIR_SIZE + PTR_SIZE,
                        parentNode->getBuffPage() + 2 * SIZE_INT +
                        (keyCount + 1) * PAIR_SIZE + PTR_SIZE,
                        (noPairs - keyCount) * PAIR_SIZE);

                //writes split key	
                writeInt(parentNode->getBuffPage(),
                        2 * SIZE_INT + keyCount * PAIR_SIZE +
                        PTR_SIZE, startKeyInSplitNode);

                //writes split node id just after split key
                writeInt(parentNode->getBuffPage(),
                        2 * SIZE_INT + (keyCount + 1) * PAIR_SIZE, splitNodeId);
            } else {

                //writes split key to k of nth pair(new apir)
                writeInt(parentNode->getBuffPage(),
                        2 * SIZE_INT + noPairs * PAIR_SIZE + PTR_SIZE,
                        startKeyInSplitNode);

                //writes splitNodeId to p(n)( at the end) 
                writeInt(parentNode->getBuffPage(),
                        2 * SIZE_INT + (noPairs + 1) * PAIR_SIZE, splitNodeId);
            }
            parentNode->setNoPairs(noPairs + 1);

            bm->unpinPage(trace[level]->getBuffPage(), true);
            delete trace[level];
            for (int i = level - 1; i >= 1; i--) {
                bm->unpinPage(trace[i]->getBuffPage(), false);
                delete trace[i];
            }
        } else {
            cout << "parent splitting" << endl;
            int newNodeId = StorageManager::allocateBlock(dbName);
            char* newNodeBuff = bm->pinPage(newNodeId);
            TreeNode *newNode = new TreeNode(newNodeBuff);

            char temp[BLOCK_SIZE + 1];
            moveBytes(parentNode->getBuffPage() + 2 * SIZE_INT,
                    temp, BLOCK_SIZE - 2 * SIZE_INT);

            int keyCount;
            int ithKey = readInt(temp, PTR_SIZE);

            for (keyCount = 0; keyCount < maxNoPairs &&
                    startKeyInSplitNode > ithKey; keyCount++) {

                ithKey = readInt(temp,
                        (keyCount + 1) * PAIR_SIZE + PTR_SIZE);
            }

            if (keyCount < maxNoPairs) {

                moveBytes(temp + keyCount * PAIR_SIZE + PTR_SIZE,
                        temp + (keyCount + 1) * PAIR_SIZE + PTR_SIZE,
                        (maxNoPairs - keyCount) * PAIR_SIZE);

                writeInt(temp, keyCount * PAIR_SIZE + PTR_SIZE,
                        startKeyInSplitNode);

                writeInt(temp, (keyCount + 1) * PAIR_SIZE, splitNodeId);
            } else {

                writeInt(temp, maxNoPairs * PAIR_SIZE + PTR_SIZE,
                        startKeyInSplitNode);

                writeInt(temp, (maxNoPairs + 1) * PAIR_SIZE, splitNodeId);
            }

            moveBytes(temp, parentNode->getBuffPage() + 2 * SIZE_INT,
                    (maxNoPairs / 2) * PAIR_SIZE + PTR_SIZE);

            int splitKey = readInt(temp,
                    (maxNoPairs / 2) * PAIR_SIZE + PTR_SIZE);

            moveBytes(temp + (maxNoPairs / 2 + 1) * PAIR_SIZE,
                    newNode->getBuffPage() + 2 * SIZE_INT,
                    ((maxNoPairs + 1) / 2) * PAIR_SIZE + PTR_SIZE);

            parentNode->setNoPairs(maxNoPairs / 2);
            newNode->setNoPairs((maxNoPairs + 1) / 2);
            newNode->setIsLeaf(0);

            bm->unpinPage(newNodeId, true);
            delete newNode;

            insertInParent(parentNode, splitKey,
                    newNodeId, trace, level - 1);

            bm->unpinPage(trace[level]->getBuffPage(), true);
            delete trace[level];
        }
    }
    cout << "done" << endl;
}
示例#4
0
void BPlusTree::insertEntry(int key, int rid) {

    BufferManager *bm = BufferManager::getInstance(dbName);
    int height;
    TreeNode **trace = new TreeNode *[10];
    for (int i = 0; i < 10; i++)
        trace[i] = NULL;

    TreeNode *leafNode = getLeaf(key, trace, &height);
    //cout<<endl<<"height of the tree: "<<height<<endl;
    if (leafNode == NULL)
        cout << "exception null node" << endl;

    cout << "lookup " << lookUpWithoutUnpin(key, leafNode) << endl;
    if (lookUpWithoutUnpin(key, leafNode) != -1) {
        cout << "key already exists" << endl;
        for (int i = height; i >= 1; i--) {
            //cout<<"unpinning trace:"<<endl;
            bm->unpinPage(trace[i]->getBuffPage(), false);
            delete trace[i];
        }
    }
    else {

        int nofPairs = readInt(leafNode->getBuffPage(), 0);
        //if num of pairs less than n-1
        if (nofPairs < maxNoPairs) {

            insertInLeaf(leafNode, key, rid);
            if (height != 0) {

                bm->unpinPage(leafNode->getBuffPage(), true);
                //cout<<"unpinning the leaf node which is not a root"<<endl;
            }
            //delete leafNode;			

            for (int i = height - 1; i >= 1; i--) {
                //cout<<"unpinning trace:"<<endl;
                bm->unpinPage(trace[i]->getBuffPage(), false);
                delete trace[i];
            }

        } else {
            int newLeafId = StorageManager::allocateBlock(dbName);
            char* newLeafNodeBuff = bm->pinPage(newLeafId);
            TreeNode *newLeafNode = new TreeNode(newLeafNodeBuff);

            int divideKeyOffset = maxNoPairs / 2;
            //cout<<"divideKeyOffset: "<<divideKeyOffset<<endl;
            int divideKey = readInt(leafNode->getBuffPage(),
                    2 * SIZE_INT + divideKeyOffset * PAIR_SIZE + PTR_SIZE);

            cout << "divideKey: " << divideKey << endl;
            if (key < divideKey) {

                moveBytes(leafNode->getBuffPage() +
                        2 * SIZE_INT + divideKeyOffset*PAIR_SIZE,
                        newLeafNode->getBuffPage() + 2 * SIZE_INT,
                        (maxNoPairs - divideKeyOffset) * PAIR_SIZE);

                //writing "nofPairs" into new leaf				
                //writeInt(newLeafNode->getBuffPage(),0,(maxNoPairs+1)/2);
                newLeafNode->setNoPairs((maxNoPairs + 1) / 2);

                //writing "isLeaf" into new leaf
                //writeInt(newLeafNode->getBuffPage(),SIZE_INT,1);
                newLeafNode->setIsLeaf(1);

                //copying P(n) of leaf to P(n) of new leaf
                moveBytes(leafNode->getBuffPage() +
                        BLOCK_SIZE - PTR_SIZE,
                        newLeafNode->getBuffPage() +
                        BLOCK_SIZE - PTR_SIZE, PTR_SIZE);

                //make p(n) of leaf to point to new leaf
                writeInt(leafNode->getBuffPage(),
                        BLOCK_SIZE - PTR_SIZE, newLeafId);

                leafNode->setNoPairs(maxNoPairs / 2);

                insertInLeaf(leafNode, key, rid);
                bm->unpinPage(newLeafId, true);

                insertInParent(leafNode, divideKey,
                        newLeafId, trace, height);
            } else {

                moveBytes(leafNode->getBuffPage() +
                        2 * SIZE_INT + (divideKeyOffset + 1) * PAIR_SIZE,
                        newLeafNode->getBuffPage() + 2 * SIZE_INT,
                        (maxNoPairs - divideKeyOffset - 1) * PAIR_SIZE);

                //writing "nofPairs" into new leaf				
                //writeInt(newLeafNode->getBuffPage(),0,maxNoPairs-divideKeyOffset-1);
                newLeafNode->setNoPairs(maxNoPairs - divideKeyOffset - 1);

                //writing "isLeaf" into new leaf
                //writeInt(newLeafNode->getBuffPage(),SIZE_INT,1);
                newLeafNode->setIsLeaf(1);

                //copying P(n) of leaf to P(n) of new leaf
                moveBytes(leafNode->getBuffPage() +
                        BLOCK_SIZE - PTR_SIZE, newLeafNode->getBuffPage() +
                        BLOCK_SIZE - PTR_SIZE, PTR_SIZE);

                //make p(n) of leaf to point to new leaf
                writeInt(leafNode->getBuffPage(),
                        BLOCK_SIZE - PTR_SIZE, newLeafId);

                //writing "nofPairs" into leaf	
                leafNode->setNoPairs(divideKeyOffset + 1);

                insertInLeaf(newLeafNode, key, rid);

                int startKey = readInt(newLeafNode->getBuffPage(),
                        2 * SIZE_INT + PTR_SIZE);

                bm->unpinPage(newLeafId, true);
                //cout<<"task completed and unpinnednew leaf id"<<endl;			
                insertInParent(leafNode, startKey,
                        newLeafId, trace, height);

            }
        }
        //bm->unpinPage(leafId,true);
        cout << endl << key << " inserted" << endl << endl;
    }
    //free (trace);	 	
    //cout<<"no of pairs in root: "<<readInt(root->getBuffPage(), 0)<<endl;   	
}
示例#5
0
文件: bt.cpp 项目: ankitsingh/DBMS
void BPlusTree::deleteFromNode(TreeNode* N, int key) {

    BufferManager *bm = BufferManager::getInstance();

    //finding the location of pair to be deleted
    int i;
    for(i=1;i<=N->getTotalPairs();i++) {
        if(N->getKey(i)==key) break;
    }
    //deleting the pair
    moveBytes( N->getBuffPage(), 8*i, 8+8*i, (N->getTotalPairs()-i+1)*8+4 );
    N->updateSlot(1, N->getTotalPairs()-1);

    //if N is root AND has only one child
    if(N->getSlot(BLOCK_SIZE/4)==-1 && N->getSlot(1)==1) {
        //delete that node and make its only child as root
        int newRootId = N->getSlot(3);
        root = new TreeNode(bm->pinPage(dbName, N->getSlot(3)));
        int blockToFree = N->getSlot(BLOCK_SIZE/4-1);
        bm->unpinPage(dbName, blockToFree, true);
        StorageManager::freeBlock(dbName, blockToFree);
        root->updateSlot(BLOCK_SIZE/4, -1);
    }
    else {
        int parentPtr = readInt(N->getBuffPage(), BLOCK_SIZE-4);
        TreeNode* parent = new TreeNode(bm->pinPage(dbName, parentPtr));
        int loc=parent->findPtr(N->getNodeId());

        bool correct;
        int NDashId,keyDash;
        //finding next or previous node and the value between them 
        if(loc>1) {
            correct=true;
            NDashId = loc-1;
            keyDash = parent->getKey(loc-1);
        } else {
            correct=false;
            NDashId = loc+1;
            keyDash = parent->getKey(loc);
        }

        TreeNode* NDash = new TreeNode(bm->pinPage(dbName, NDashId));

        //if N and NDash can coalesce in one node
        if(N->getTotalPairs()+NDash->getTotalPairs()-1 == BT_N) {
            //swapping if successive nodes r in reverse order
            if(correct==false) {
                TreeNode* temp;
                temp = N;
                N = NDash;
                NDash = temp;
            }
    
            //coalescing nodes
            if(!N->isLeaf()) {
                int num = NDash->getTotalPairs();
                NDash->updateSlot(2*NDash->getTotalPairs()+2, keyDash);
                for(int i=0;i<(N->getTotalPairs()*2);i++) {
                    NDash->updateSlot(2*NDash->getTotalPairs()+2+i, N->getSlot(i+2));
                    NDash->updateSlot(1,NDash->getTotalPairs()+num);
                }
            }
            else {
                int num = NDash->getTotalPairs();
                NDash->updateSlot(2*NDash->getTotalPairs()+2, keyDash);
                for(int i=0;i<(N->getTotalPairs()*2);i++)
                    NDash->updateSlot(2*NDash->getTotalPairs()+2+i, N->getSlot(i+2));
                NDash->updateSlot(1,NDash->getTotalPairs()+num);
                NDash->updateSlot(2+2*BT_N+1,N->getSlot(2+2*BT_N+1));
            }
            deleteFromNode(parent, keyDash);
        }

        //if NDash is predecessor
        if(correct==true){
            if(!N->isLeaf()) {
                //removing last key and pointer to next leaf
                int lastKey = NDash->getSlot(2+NDash->getTotalPairs()*2);
                int lastPtr = NDash->getSlot(2+NDash->getTotalPairs()*2+1);
                NDash->updateSlot(1,NDash->getTotalPairs()+1);
                //adding one pair to N
                moveBytes(N->getBuffPage(), 16, 8, N->getTotalPairs()*8+4);
                N->updateSlot(1, N->getTotalPairs()+1);
                N->updateSlot(3, lastPtr);
                N->updateSlot(4, keyDash);
                //replacing keyDash in parent by the removed key
                int location = parent->findKey(keyDash);
                parent->updateSlot(2+2*location, lastKey);
            } else {
                //removing last key and pointer to next leaf
                int lastKey = NDash->getSlot(2+NDash->getTotalPairs()*2);
                int lastPtr = NDash->getSlot(2+NDash->getTotalPairs()*2-1);
                NDash->updateSlot(1,NDash->getTotalPairs()+1);
                //adding one pair to N
                moveBytes(N->getBuffPage(), 16, 8, N->getTotalPairs()*8);
                N->updateSlot(1, N->getTotalPairs()+1);
                N->updateSlot(3, lastPtr);
                N->updateSlot(4, keyDash);
                //replacing keyDash in parent by the removed key
                int location = parent->findKey(keyDash);
                parent->updateSlot(2+2*location, lastKey);
            }
        } else {
            if(!NDash->isLeaf()) {
                //removing last key and pointer to next leaf
                int lastKey = N->getSlot(2+N->getTotalPairs()*2);
                int lastPtr = N->getSlot(2+N->getTotalPairs()*2+1);
                N->updateSlot(1,N->getTotalPairs()+1);
                //adding one pair to NDash
                moveBytes(NDash->getBuffPage(), 16, 8, NDash->getTotalPairs()*8+4);
                NDash->updateSlot(1, NDash->getTotalPairs()+1);
                NDash->updateSlot(3, lastPtr);
                NDash->updateSlot(4, keyDash);
                //replacing keyDash in parent by the removed key
                int location = parent->findKey(keyDash);
                parent->updateSlot(2+2*location, lastKey);
            } else {
                //removing last key and pointer to next leaf
                int lastKey = N->getSlot(2+N->getTotalPairs()*2);
                int lastPtr = N->getSlot(2+N->getTotalPairs()*2-1);
                N->updateSlot(1,N->getTotalPairs()+1);
                //adding one pair to NDash
                moveBytes(NDash->getBuffPage(), 16, 8, NDash->getTotalPairs()*8);
                NDash->updateSlot(1, NDash->getTotalPairs()+1);
                NDash->updateSlot(3, lastPtr);
                NDash->updateSlot(4, keyDash);
                //replacing keyDash in parent by the removed key
                int location = parent->findKey(keyDash);
                parent->updateSlot(2+2*location, lastKey);
            }
        }
    }
}