void InnerNode::add_pivot(Slice key, bid_t nid, std::vector<DataNode*>& path) { assert(path.back() == this); if (status_ == kSkeletonLoaded) { load_all_msgbuf(); } vector<Pivot>::iterator it = std::lower_bound(pivots_.begin(), pivots_.end(), key, KeyComp(tree_->options_.comparator)); MsgBuf* mb = new MsgBuf(tree_->options_.comparator); pivots_.insert(it, Pivot(key.clone(), nid, mb)); pivots_sz_ += pivot_size(key); msgbufsz_ += mb->size(); set_dirty(true); if (pivots_.size() + 1 > tree_->options_.inner_node_children_number) { split(path); } else { while(path.size()) { path.back()->unlock(); path.back()->dec_ref(); path.pop_back(); } } }
void InnerNode::split(std::vector<DataNode*>& path) { assert(pivots_.size() > 1); size_t n = pivots_.size()/2; size_t n1 = pivots_.size() - n - 1; Slice k = pivots_[n].key; InnerNode *ni = tree_->new_inner_node(); ni->bottom_ = IS_LEAF(pivots_[n].child); assert(ni); ni->first_child_ = pivots_[n].child; ni->first_msgbuf_ = pivots_[n].msgbuf; ni->pivots_.resize(n1); std::copy(pivots_.begin() + n + 1, pivots_.end(), ni->pivots_.begin()); pivots_.resize(n); size_t pivots_sz1 = 0; size_t msgcnt1 = 0; size_t msgbufsz1 = 0; msgcnt1 += ni->first_msgbuf_->count(); msgbufsz1 += ni->first_msgbuf_->size(); for(size_t i = 0; i < ni->pivots_.size(); i++) { pivots_sz1 += pivot_size(ni->pivots_[i].key); msgcnt1 += ni->pivots_[i].msgbuf->count(); msgbufsz1 += ni->pivots_[i].msgbuf->size(); } ni->pivots_sz_ = pivots_sz1; ni->msgcnt_ = msgcnt1; ni->msgbufsz_ = msgbufsz1; pivots_sz_ -= (pivots_sz1 + pivot_size(k)); msgcnt_ -= msgcnt1; msgbufsz_ -= msgbufsz1; ni->set_dirty(true); ni->dec_ref(); path.pop_back(); unlock(); dec_ref(); // propagation if( path.size() == 0) { // i'm root InnerNode *nr = tree_->new_inner_node(); assert(nr); nr->bottom_ = false; nr->first_child_ = nid_; MsgBuf* mb0 = new MsgBuf(tree_->options_.comparator); nr->first_msgbuf_ = mb0; nr->msgbufsz_ += mb0->size(); nr->pivots_.resize(1); MsgBuf* mb1 = new MsgBuf(tree_->options_.comparator); nr->pivots_[0] = Pivot(k.clone(), ni->nid_, mb1); nr->pivots_sz_ += pivot_size(k); nr->msgbufsz_ += mb1->size(); nr->set_dirty(true); tree_->pileup(nr); // need not do nr->dec_ref() here } else { // propagation InnerNode* parent = (InnerNode*) path.back(); assert(parent); parent->add_pivot(k, ni->nid_, path); } }