Пример #1
0
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);
}
Пример #2
0
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);
	}
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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...";
	}
}
Пример #6
0
void balanceTree(tree *t) {

	node* newroot = NULL;

	newroot = balanceNode(t->root);

	if(newroot != t->root)
		t->root = newroot;	
}
Пример #7
0
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;
}
Пример #8
0
  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);
    }
  }
Пример #9
0
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
Пример #10
0
void TCBinaryObjectTree::balance(void)
{
	balanceNode(rootNode);
}
Пример #11
0
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);
}
Пример #12
0
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();
}
Пример #13
0
void balance(Tree* tp)
{          
  tp->root = balanceNode(tp->root);
}
Пример #14
0
void insert(Tree* tp,char* data)
{
  tp->root = insertNode(tp->root,data);
  tp->root = balanceNode(tp->root);
}