node* balanceNode(node* nod) { node* newroot = NULL; int bf = 0; if(nod->left) nod->left = balanceNode(nod->left); if(nod->right) nod->right= balanceNode(nod->right); bf = balanceFactor(nod); if(bf >= 2) { if(balanceFactor(nod->left) <= -1 ) newroot = rotateLR(nod); else newroot = rotateLL(nod); }else if(bf <= -2) { if(balanceFactor(nod->right)<= 1) newroot = rotateRL(nod); else newroot = rotateRR(nod); }else newroot = nod; return(newroot); }
void TCBinaryObjectTree::balanceNode(TCBinaryObjectTreeNode *&node) { if (node) { TCBinaryObjectTreeNode *middleNode = findMiddleNode(node); if (middleNode != node) { TCBinaryObjectTreeNode *middleNodeParent = findNodeParent(node, middleNode); if (middleNodeParent) { TCBinaryObjectTreeNode *spot = middleNode; if (middleNode == middleNodeParent->left) { while (spot->right) { spot = spot->right; } spot->right = node; node = middleNode; middleNodeParent->left = NULL; } else { } } } balanceNode(node->left); balanceNode(node->right); } }
Node* balanceNode(Node* n) { if (n != NULL) { n->l = balanceNode(n->l); n->r = balanceNode(n->r); if (depth(n->r) > depth(n->l)+1) { n = rotateACW(n); } if (depth(n->l) > depth(n->r)+1) { n = rotateCW(n); } } return n; }
static TreeNode * insertIntoTree(AVLTree * tree, TreeNode * node, void * data, Boolean * success) { if(node == NULL) return newTreeNode(data); int comparision = tree->compare(data, node->data); if(comparision == 0) { *success = false; return node; } int direction = comparision > 0 ? RIGHT : LEFT; if(direction == RIGHT) { node->right = insertIntoTree(tree, node->right, data, success); } else { node->left = insertIntoTree(tree, node->left, data, success); } updateHeight(node); node = balanceNode(node); return node; }
void AVL::checkNewBalance(Node* currentNode) { if (!isBalanced(currentNode)) { //cout << "balancing " << currentNode->getData() << "..."; balanceNode(currentNode); } //cout << currentNode->getData() << " balanced..."; while (currentNode->getParent() != NULL) { currentNode = currentNode->getParent(); //cout << "Checking balance on " << currentNode->getData() << "..."; if (!isBalanced(currentNode)) { //cout << "balancing " << currentNode->getData() << "..."; balanceNode(currentNode); } //cout << currentNode->getData() << " balanced..."; } }
void balanceTree(tree *t) { node* newroot = NULL; newroot = balanceNode(t->root); if(newroot != t->root) t->root = newroot; }
static TreeNode * removeNode(AVLTree * tree, TreeNode * node, void * data, void ** removedData) { if(node == NULL) return NULL; int comparision = tree->compare(data, node->data); if(comparision > 0) { node->right = removeNode(tree, node->right, data, removedData); } if(comparision < 0) { node->left = removeNode(tree, node->left, data, removedData); } if(comparision == 0) { *removedData = node->data; if(node->left == NULL && node->right == NULL) /*leaf node*/ { destroyNode(node); node = NULL; return node; } else if(node->left != NULL && node->right != NULL) { node->data = replaceWithData(node->left, data); node->left = removeNode(tree, node->left, data, removedData); } else if(node->left != NULL) /*only left node*/ { TreeNode * leftNode = node->left; *removedData = node->data; destroyNode(node); node = leftNode; } else /*only right node*/ { TreeNode * rightNode = node->right; *removedData = node->data; destroyNode(node); node = rightNode; } } updateHeight(node); node = balanceNode(node); return node; }
void DBVH::balanceSubTree( DBVHNode* subTree ) { if(subTree) { //pivot node's left child is the left node's child with the largest depth int lHeight, rHeight; lHeight = heightOfSubTree(subTree->left); rHeight = heightOfSubTree(subTree->right); if(abs(lHeight - rHeight) > 1) balanceNode(subTree); makeAABBs(subTree); } }
bool deleteKey(TreeNodePtr node, LSQ_IntegerIndexT key, int pos, bool needFree){ //ALWAYS, on successful (with true on return) call of this function, we need to //decrease .subtreeKeyCount; bool res = true; if(NULL == node) return false; //1 if(isLeaf(node)){ if(!isKeyFound(node, pos, key)) return false; excludeKey(node, pos, needFree); return true; } //2 //if key found in internal node if(isKeyFound(node, pos, key)){ //we always have left and right children of key splitter assert(node->nodes[pos] != NULL && node->nodes[pos + 1] != NULL); //we always have to free internal key assert(needFree); if(internalKeyDelete(node, pos, 0, FD_BY_RIGHT_SIDE)) return res; if(internalKeyDelete(node, pos, 1, FD_BY_LEFT_SIDE)) return res; //keyCounts left < t && right < t: mergeToLeft(node, pos); res = deleteKey(node->nodes[pos], key, t-1, needFree); if(res) node->subtreeKeyCount[pos]--; return res; } //3: pivot/merge //key is not found yet and we don't need free it? FAIL. bad assert //assert(needFree && node->nodes[pos]->keyCount >= MIN_KEY_COUNT); pos = balanceNode(node, pos); assert(pos < node->childCount); res = deleteKey(node->nodes[pos], key, getItemOrNext(node->nodes[pos], key), needFree); if(res) node->subtreeKeyCount[pos]--; return res; } //deleteKey
void TCBinaryObjectTree::balance(void) { balanceNode(rootNode); }
void Balancer::perfBalanceStrongestDevice(Cluster &cluster, Decomposition& decomp) { WorkQueue work_queue; WorkRequest work_request; double total_weight(0.0); double min_edge_weight(0.0); double procTime(0.0); double commTime(0.0); double timeEst = procTime; bool changed(false); const int kStrongest(3); const int kConfig = kStrongest; Node &root = cluster.getNode(0); const size_t kNumBlocks = decomp.getNumSubDomains(); // initialize block directory cluster.setNumBlocks(kNumBlocks); //get total iterations per second for cluster for (unsigned int node = 0; node < cluster.getNumNodes(); ++node) { total_weight += cluster.getNode(node).getTotalWeight(kConfig); min_edge_weight += cluster.getNode(node).getMinEdgeWeight(kConfig); } // quick estimation of runtime procTime = (0.0 == total_weight) ? std::numeric_limits<double>::max() : kNumBlocks / total_weight; commTime = (0.0 == min_edge_weight) ? std::numeric_limits<double>::max() : kNumBlocks / min_edge_weight; timeEst = procTime; timeEst += (std::numeric_limits<double>::max() - procTime >= commTime) ? commTime : 0.0; //printf("timeEst:%f\n", timeEst); // place all of the blocks on the root node for (size_t i = 0; i < kNumBlocks; ++i) root.incrementBalCount(); /*fprintf(stderr, "perfBalance: \n\ttime est: %f sec\n\tprocTime: %f sec\n\tcommTime: %f \ sec\n\ttotal weight:%e \n\tmin edge weight:%e.\n", timeEst, procTime, commTime, total_weight, min_edge_weight); // */ do { changed = false; //printf("beginning, changed == %s\n", (changed == true) ? "true" : "false"); // balance the work between nodes and root for (unsigned int cpu_index = 1; cpu_index < cluster.getNumNodes(); ++cpu_index) { Node& cpu_node = cluster.getNode(cpu_index); int work_deficit = cpu_node.getTotalWorkNeeded(timeEst, kConfig) - cpu_node.getBalCount(); if (0 > work_deficit) { // node has extra work //printf("cpu node %d has %d extra blocks.\n", cpu_index, work_deficit); int extra_blocks = abs(work_deficit); for (int block_index = 0; (block_index < extra_blocks) && (0 < cpu_node.getBalCount()); ++block_index) { // move block from child to parent cpu_node.decrementBalCount(); root.incrementBalCount(); changed = true; } } else if (0 < work_deficit) { //child needs more work work_request.setTimeDiff(timeEst - cpu_node.getBalTimeEst(0, kConfig)); work_request.setIndex(cpu_index); work_queue.push(work_request); } } // go through all of root nodes gpus for (unsigned int index = 0; index < root.getNumChildren(); ++index) { Node& node = root.getChild(index); int work_deficit = node.getTotalWorkNeeded(timeEst, kConfig) - node.getBalCount(); if (0 > work_deficit) { // child has extra work //printf("root child %d has %d blocks and only needs %d blocks.\n", index, // node.getBalCount(), node.getTotalWorkNeeded(timeEst, kConfig)); int extra_blocks = abs(work_deficit); for (int block_index = 0; (block_index < extra_blocks) && (0 < node.getBalCount()); ++block_index) { // move block from child to parent node.decrementBalCount(); root.incrementBalCount(); //changed = true; } } else if (0 < work_deficit) { // child needs more work work_request.setTimeDiff(timeEst - node.getBalTimeEst(0, kConfig)); work_request.setIndex(-1 * index); // hack so I know to give to one of root's children work_queue.push(work_request); } } /* at this point we have all extra blocks, and now we need to distribute blocks to children that need it */ //printf("after collecting extra blocks from children, changed == %s\n", // (changed == true) ? "true" : "false"); // while root has extra blocks and there are requests left to fill while (0 < (root.getBalCount() - root.getTotalWorkNeeded(timeEst, kConfig)) && !work_queue.empty()) { //printf("root needs %d blocks and has %d blocks.\n", // root.getTotalWorkNeeded(timeEst, kConfig), root.getBalCount()); // get largest request WorkRequest tmp = work_queue.top(); work_queue.pop(); double newTimeDiff = 0.0; int id = tmp.getIndex(); if (id <= 0) { // local child //printf("giving block to local child.\n"); id = -1 * id; root.decrementBalCount(); root.getChild(id).incrementBalCount(); newTimeDiff = timeEst - root.getChild(id).getBalTimeEst(0, kConfig); changed = true; } else { // request was from another node in cluster //printf("giving block to cpu node child.\n"); root.decrementBalCount(); cluster.getNode(id).incrementBalCount(); newTimeDiff = timeEst - cluster.getNode(id).getBalTimeEst(0, kConfig); changed = true; } // if there is still work left to do put it back on // the queue so that it will reorder correctly if (0 < newTimeDiff) { tmp.setTimeDiff(newTimeDiff); work_queue.push(tmp); } } //printf("after distributing extra blocks to cpu nodes, changed == %s\n", // (changed == true) ? "true" : "false"); // balance the work within each node for (unsigned int node = 0; node < cluster.getNumNodes(); ++node) { balanceNode(cluster.getNode(node), timeEst, kConfig); //changed |= balanceNode(cluster.getNode(node), timeEst, kConfig); } //printf("after balancing within each node, changed == %s\n", // (changed == true) ? "true" : "false"); //printClusterBalCount(cluster); //printf("************* END OF BALANCE ITERATION ***********\n"); } while (changed); }
void Balancer::perfBalance(Cluster &cluster, Decomposition& decomp, const int kConfig) { WorkQueue work_queue; WorkRequest work_request; double total_weight(0.0); double min_edge_weight(0.0); double procTime(0.0); double commTime(0.0); double timeEst = procTime; bool changed(false); const int kGPUOnly(2); const int kStrongest(3); Node &root = cluster.getNode(0); size_t num_blocks = decomp.getNumSubDomains(); // initialize block directory cluster.setNumBlocks(num_blocks); //get total iterations per second for cluster for (unsigned int node = 0; node < cluster.getNumNodes(); ++node) { total_weight += cluster.getNode(node).getTotalWeight(kConfig); min_edge_weight += cluster.getNode(node).getMinEdgeWeight(kConfig); } // quick estimation of runtime procTime = num_blocks / total_weight; commTime = num_blocks / min_edge_weight; timeEst = procTime; if (0.0 < min_edge_weight) timeEst += commTime; if (kGPUOnly == kConfig) { perfBalanceGPU(cluster, decomp, timeEst); } else if (kStrongest == kConfig) { perfBalanceStrongestDevice(cluster, decomp); } else { // perform initial task distribution for (size_t i = 0; i < num_blocks; ++i) root.incrementBalCount(); /*fprintf(stderr, "perfBalance: \n\ttime est: %f sec\n\tprocTime: %f sec\n\tcommTime: %f \ sec\n\ttotal weight:%e \n\tmin edge weight:%e.\n", timeEst, procTime, commTime, total_weight, min_edge_weight); // */ do { changed = false; // balance the work between nodes and root for (unsigned int cpu_index = 1; cpu_index < cluster.getNumNodes(); ++cpu_index) { Node& cpu_node = cluster.getNode(cpu_index); int work_deficit = cpu_node.getTotalWorkNeeded(timeEst, kConfig) - cpu_node.getBalCount(); if (0 > work_deficit) { // node has extra work int extra_blocks = abs(work_deficit); for (int block_index = 0; (block_index < extra_blocks) && (0 < cpu_node.getBalCount()); ++block_index) { // move block from child to parent cpu_node.decrementBalCount(); root.incrementBalCount(); changed = true; } } else if (0 < work_deficit) { //child needs more work work_request.setTimeDiff(timeEst - cpu_node.getBalTimeEst(0, kConfig)); work_request.setIndex(cpu_index); work_queue.push(work_request); } } for (unsigned int cpu_index = 0; cpu_index < root.getNumChildren(); ++cpu_index) { Node& cpu_node = root.getChild(cpu_index); int work_deficit = cpu_node.getTotalWorkNeeded(timeEst, kConfig) - cpu_node.getBalCount(); if (0 > work_deficit) { // child has extra work int extra_blocks = abs(work_deficit); for (int block_index = 0; (block_index < extra_blocks) && (0 < cpu_node.getBalCount()); ++block_index) { // move block from child to parent cpu_node.decrementBalCount(); root.incrementBalCount(); changed = true; } } else if (0 < work_deficit) { // child needs more work work_request.setTimeDiff(timeEst - cpu_node.getBalTimeEst(0, kConfig)); work_request.setIndex(-1 * cpu_index); // hack so I know to give to one of root's children work_queue.push(work_request); } } /* at this point we have all extra blocks, and now we need to distribute blocks to children that need it */ while (0 < root.getBalCount() && // there are blocks left to give !work_queue.empty()) { // there are requests left to fill // get largest request WorkRequest tmp = work_queue.top(); work_queue.pop(); double newTimeDiff = 0.0; int id = tmp.getIndex(); if (id <= 0) { // local child id = -1 * id; root.decrementBalCount(); root.getChild(id).incrementBalCount(); newTimeDiff = timeEst - root.getChild(id).getBalTimeEst(0, kConfig); changed = true; } else { // request was from another node in cluster root.decrementBalCount(); cluster.getNode(id).incrementBalCount(); newTimeDiff = timeEst - cluster.getNode(id).getBalTimeEst(0, kConfig); changed = true; } // if there is still work left to do put it back on // the queue so that it will reorder correctly if (0 < newTimeDiff) { tmp.setTimeDiff(newTimeDiff); work_queue.push(tmp); } } // balance the work within each node for (unsigned int node = 0; node < cluster.getNumNodes(); ++node) { changed |= balanceNode(cluster.getNode(node), timeEst, kConfig); } } while (changed); } /* now that we know where everything should go, distribute the blocks */ cluster.distributeBlocks(&decomp); /* the work is balanced, so we can fill the block directory */ cluster.storeBlockLocs(); }
void balance(Tree* tp) { tp->root = balanceNode(tp->root); }
void insert(Tree* tp,char* data) { tp->root = insertNode(tp->root,data); tp->root = balanceNode(tp->root); }