예제 #1
0
파일: msg.cpp 프로젝트: MissGentoo/cascadb
void MsgBuf::append(MsgBuf::Iterator first, MsgBuf::Iterator last)
{
    MsgBuf::Iterator it = container_.begin();
    MsgBuf::Iterator jt = first;
    KeyComp comp(comp_);

    while(jt != last) {
#ifdef FAST_VECTOR
        it = container_.lower_bound(it, jt->key, comp);
#else
        it = lower_bound(it, container_.end(), jt->key, comp);
#endif
        if (it == container_.end() || it->key != jt->key) {
            // important, it maybe invalid after insertion
            it = container_.insert(it, *jt);
            size_ += jt->size();
        } else {
            size_ -= it->size();
            it->destroy();
            *it = *jt;
            size_ += it->size();
        }
        jt ++;
    }
}
예제 #2
0
파일: msg.cpp 프로젝트: MissGentoo/cascadb
void MsgBuf::write(const Msg& msg)
{
#ifdef FAST_VECTOR
    MsgBuf::Iterator it = container_.lower_bound(msg, KeyComp(comp_));
#else
    MsgBuf::Iterator it = lower_bound(container_.begin(), 
        container_.end(), msg, KeyComp(comp_));
#endif
    if (it == end() || it->key != msg.key) {
        container_.insert(it, msg);
        size_ += msg.size();
    } else {
        size_ -= it->size();
        it->destroy();
        *it = msg;
        size_ += msg.size();
    }
}
예제 #3
0
파일: node.cpp 프로젝트: jameswei/cascadb
bool LeafNode::cascade(MsgBuf *mb, InnerNode* parent)
{
    write_lock();

    if (status_ == kSkeletonLoaded) {
        load_all_buckets();
    }

    // lock message buffer from parent
    mb->write_lock();
    size_t oldcnt = mb->count();
    size_t oldsz = mb->size();

    Slice anchor = mb->begin()->key.clone();

    // merge message buffer into leaf
    RecordBuckets res(tree_->options_.leaf_node_bucket_size);

    MsgBuf::Iterator it = mb->begin();
    RecordBuckets::Iterator jt = records_.get_iterator();
    while (it != mb->end() && jt.valid()) {
        int n = tree_->options_.comparator->compare(it->key, jt.record().key);
        if (n < 0) {
            if (it->type == Put) {
                res.push_back(to_record(*it));
            } else {
                // just throw deletion to non-exist record
                it->destroy();
            }
            it ++;
        } else if (n > 0) {
            res.push_back(jt.record());
            jt.next();
        } else {
            if (it->type == Put) {
                res.push_back(to_record(*it));
            }
            // old record is deleted
            it ++;
            jt.record().key.destroy();
            jt.record().value.destroy();
            jt.next();
        }
    }
    for (; it != mb->end(); it++) {
        if (it->type == Put) {
            res.push_back(to_record(*it));
        }
    }
    while(jt.valid()) {
        res.push_back(jt.record());
        jt.next();
    }
    records_.swap(res);

    refresh_buckets_info();
    set_dirty(true);

    // clear message buffer
    mb->clear();
    parent->msgcnt_ = parent->msgcnt_ + mb->count() - oldcnt;
    parent->msgbufsz_ = parent->msgbufsz_ + mb->size() - oldsz;

    // unlock message buffer
    mb->unlock();
    // crab walk
    parent->unlock();

    if (records_.size() == 0) {
        merge(anchor);
    } else if (records_.size() > 1 && (records_.size() > 
        tree_->options_.leaf_node_record_count || size() > 
        tree_->options_.leaf_node_page_size)) {
        split(anchor);
    } else {
        unlock();
    }
    
    anchor.destroy();
    return true;
}