void BTreeBuilder::build( ByteInputStream &sortedInputStream, RecordNum nEntriesTotal, double fillFactor) { assert(fillFactor <= 1.0); assert(fillFactor > 0); try { if (pLeafNodeAccessor->hasFixedWidthEntries() && pNonLeafNodeAccessor->hasFixedWidthEntries()) { buildBalanced(sortedInputStream, 0, nEntriesTotal, fillFactor); } else if (pNonLeafNodeAccessor->hasFixedWidthEntries()) { buildTwoPass( sortedInputStream, nEntriesTotal, fillFactor); } else { assert(!pLeafNodeAccessor->hasFixedWidthEntries()); buildUnbalanced(sortedInputStream, nEntriesTotal, fillFactor); } } catch (...) { try { levels.clear(); } catch (...) { // TODO: trace suppressed excn } throw; } levels.clear(); }
void balance(Tree* tree) { int nodes = numberOfNodes(tree); //1 eftersom ett träd med två noder alltid kommer vara balanserat. if (nodes > 1) { if (actualDepth(tree->root, 0, 0) > theoreticalDepth(tree)) { int *arr = (int*)calloc(numberOfNodes(tree), sizeof(int)); moveToArr(tree->root, arr, 0); emptyTree(tree, tree->root); buildBalanced(tree, arr, nodes); free(arr); //vill inte skriva ut :( //printf("Your tree is now balanced!\n"); } else { printf("Your tree is already balanced!\n"); } } else { printf("Your tree has to have more than one node!\n"); } }
void buildBalanced(Tree* tree, int* arr, int nodes) { if (nodes > 2) { // always choose the biggest if even (numberOfNodes/2 + 1) int middle = nodes / 2 + 1; // -1 för att array index börjar på 0 addNode(tree, arr[middle - 1]); buildBalanced(tree, arr, middle - 1); buildBalanced(tree, arr + middle, nodes - middle); } else if (nodes == 2) { addNode(tree, arr[1]); addNode(tree, arr[0]); } else { addNode(tree, arr[0]); } }
void BTreeBuilder::buildTwoPass( ByteInputStream &sortedInputStream, RecordNum nEntriesTotal, double fillFactor) { // calculate amount of space to reserve on each leaf from fillfactor uint cbReserved = getSegment()->getUsablePageSize() - sizeof(BTreeNode); cbReserved = uint(cbReserved*(1-fillFactor)); levels.resize(1); BTreeNodeAccessor &nodeAccessor = *pLeafNodeAccessor; assert(!nodeAccessor.hasFixedWidthEntries()); VariableBuildLevel *pLeafLevel = new VariableBuildLevel(*this,nodeAccessor); levels[0].reset(pLeafLevel); BTreeBuildLevel &level = getLevel(0); level.nEntriesTotal = nEntriesTotal; level.cbReserved = cbReserved; level.allocatePage(); // feed data into the leaf level; this will collect the entries for // level 1 (the parent of the leaf level) in a temp stream level.processInput(sortedInputStream); level.indexLastKey(true); // now we know how many entries to expect for level 1: the number of // leaf nodes just filled RecordNum nEntriesParent = level.iNode + 1; if (nEntriesParent == 1) { // The leaf we just filled turns out to be the root. swapRoot(); return; } // REVIEW: distinguish leaf fillFactor from non-leaf fillFactor? SharedSegInputStream pParentInputStream = pLeafLevel->getParentKeyStream(); assert(pParentInputStream); // feed buffered entries into level 1, and build up balanced from there buildBalanced(*pParentInputStream,1,nEntriesParent,fillFactor); }