#include using namespace std ; #include "btree.hxx" // (c) J. Dean Brock, 1998, 1999, 2002, 2003 // Written for UNCA CSCI 343 // Routines to update the B+-tree void bTree::update(const char *key, int value) { char leftMaxKey[KEYSIZE] ; int rightPos = -1 ; simpRecT newRec ; bzero((char *)&newRec, sizeof(simpRecT)) ; (void) strncpy(&newRec.name[0], key, KEYSIZE) ; newRec.value = value ; updateInt(0, newRec, &leftMaxKey[0], rightPos) ; if (rightPos != -1) { // We gotta split the root and raise the tree a level int leftPos ; leftPos = addBlock(btRoot) ; // Yeah... the root was overwritten if (!btState) return ; clearLeaf(&btRoot) ; btRoot.recs[0].value = leftPos ; (void) strncpy(&btRoot.recs[0].name[0], leftMaxKey, KEYSIZE); btRoot.recs[1].value = rightPos ; setUsedRecords(&btRoot, 1) ; updateBlock(0, btRoot) ; } } void bTree::updateInt( int subPos, // index of subtree for update const simpRecT &newRec, // record to be inserted char splitKey[KEYSIZE], // in case of split, store split key here int &splitPos) // in case of split, store new block addr here { blockRecT subBlock ; int childSlot, found ; if (subPos == 0) subBlock = btRoot ; else { readBlock(subPos, subBlock) ; if (!btState) return ; } findLEslot(subBlock, newRec.name, childSlot, found) ; if (isLeaf(&subBlock)) { if (found) // Replacing an existing value subBlock.recs[childSlot].value = newRec.value ; else if (getUsedRecords(&subBlock) < RECSINBLK) // Adding a new value to this leaf insertRec(subBlock, childSlot, newRec) ; else { int newPos ; blockRecT newBlock ; splitBlock(subBlock, newBlock, splitKey, newRec, childSlot) ; newPos = addBlock(newBlock) ; if (!btState) return ; splitPos = newPos ; subBlock.recs[METAPNTR].value = splitPos ; } updateBlock(subPos, subBlock) ; } else { char newSplitKey[KEYSIZE] ; int newSplitPos = -1 ; updateInt(subBlock.recs[childSlot].value,newRec,newSplitKey,newSplitPos); if (newSplitPos != -1) { simpRecT newIntRec ; (void) strncpy(newIntRec.name, newSplitKey, KEYSIZE) ; newIntRec.value = subBlock.recs[childSlot].value ; subBlock.recs[childSlot].value = newSplitPos ; if (getUsedRecords(&subBlock) < RECSINBLK) // Adding a new record to this interior node. insertRec(subBlock, childSlot, newIntRec) ; else { // Spliting an interior node int newPos ; blockRecT newBlock ; splitBlock(subBlock, newBlock, splitKey, newIntRec, childSlot) ; newPos = addBlock(newBlock) ; if (!btState) return ; splitPos = newPos ; if (isLeaf(&subBlock)) subBlock.recs[METAPNTR].value = splitPos ; } updateBlock(subPos, subBlock) ; } } }