void BNode::rebalance(BNode* current_c, size_t pos_c){ if( !current_c->is_empty()) return; if( pos_c < size_c-1 && !children[pos_c+1]->is_half() ){ //ie children[pos_c+1].size >= d+1 BNode* sibling = children[pos_c+1]; if( current_c->is_leaf() ){ Block* tmp = sibling->lost_smallest_block(); current_c ->win_block( tmp );//no rebalance needed because sibling.size >= d+1 }else{ BNode* tmp = sibling->lost_smallest_child(); current_c->win_child( tmp ); } }else if( pos_c > 0 && !children[pos_c-1]->is_half() ){ //ie children[pos_b-1].size >= d+1 BNode* sibling = children[pos_c-1]; if( current_c->is_leaf() ){ Block* tmp = sibling->lost_greatest_block(); current_c ->win_block( tmp ); }else{ BNode* tmp = sibling->lost_greatest_child(); current_c->win_child( tmp ); } }else{//merge if( pos_c < size_c-1 ){ //right fusion current_c->merge( children[pos_c+1] ); children[pos_c+1]->clear(); remove_child( pos_c+1 ); }else if( pos_c > 0){ //left fusion children[pos_c-1]->merge( current_c ); current_c->clear(); remove_child( pos_c ); } } }
BTree* BTree::split(float ratio){ BTree* right = new BTree( path ); size_t blocks = root->number_blocks(); size_t number = ratio * blocks; list<BNode*> leaves; root->all_leaves(leaves); Block* tmp = NULL; for(list<BNode*>::iterator it = leaves.begin() ; it != leaves.end() ; it++) for( size_t i = 0; i<min( (*it)->get_size_b() - d, number) ; i++){ tmp = (*it)->lost_greatest_block(); cache->remove( tmp ); right->add_block( tmp ); number--; } while( number > 0){ BNode* last = root->last_leave(); tmp = last->lost_greatest_block(); cache->remove( tmp ); right->add_block( tmp ); number--; root->last_rebalance(); last = root->last_leave(); int todo = min( last->get_size_b() - d, number); for( int i = 0; i<todo; i++){ tmp = last->lost_greatest_block(); cache->remove( tmp ); right->add_block( tmp ); number--; } } return right; }