Example #1
0
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();
        }
    }
}
Example #2
0
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);
    }
}