Ejemplo n.º 1
0
TEST(InnerNode, serialize)
{
    Options opts;
    opts.comparator = new LexicalComparator();
    opts.inner_node_msg_count = 4;
    opts.inner_node_children_number = 2;
    opts.leaf_node_record_count = 4;

    Directory *dir = new RAMDirectory();
    AIOFile *file = dir->open_aio_file("tree_test");
    Layout *layout = new Layout(file, 0, opts);
    ASSERT_TRUE(layout->init(true));
    Cache *cache = new Cache(opts);
    ASSERT_TRUE(cache->init());
    Tree *tree = new Tree("", opts, cache, layout);
    ASSERT_TRUE(tree->init());

    char buffer[40960];
    Block blk(Slice(buffer, 40960), 0, 0);
    BlockReader reader(&blk);
    BlockWriter writer(&blk);

    InnerNode n1("", NID_START, tree);
    n1.bottom_ = true;
    n1.first_child_ = NID_LEAF_START;
    n1.first_msgbuf_ = new MsgBuf(opts.comparator);
    PUT(*n1.first_msgbuf_, "a", "1");
    PUT(*n1.first_msgbuf_, "b", "1");
    PUT(*n1.first_msgbuf_, "c", "1");
    n1.pivots_.resize(1);
    n1.pivots_[0].key = Slice("d").clone();
    n1.pivots_[0].child = NID_LEAF_START + 1;
    n1.pivots_[0].msgbuf = new MsgBuf(opts.comparator);

    size_t skeleton_size;
    EXPECT_TRUE(n1.write_to(writer, skeleton_size) == true);

    InnerNode n2("", NID_START, tree);
    EXPECT_TRUE(n2.read_from(reader, false) == true);

    EXPECT_TRUE(n2.bottom_ == true);
    EXPECT_EQ(NID_LEAF_START, n2.first_child_);
    EXPECT_TRUE(n2.first_msgbuf_ != NULL);
    EXPECT_EQ(3U, n2.first_msgbuf_->count());
    CHK_MSG(n2.first_msgbuf_->get(0), Put, "a", "1");
    CHK_MSG(n2.first_msgbuf_->get(1), Put, "b", "1");
    CHK_MSG(n2.first_msgbuf_->get(2), Put, "c", "1");
    EXPECT_EQ(1U, n2.pivots_.size());
    EXPECT_EQ("d", n2.pivots_[0].key);
    EXPECT_EQ(NID_LEAF_START+1, n2.pivots_[0].child);
    EXPECT_TRUE(n2.pivots_[0].msgbuf != NULL);
    EXPECT_EQ(0U, n2.pivots_[0].msgbuf->count());

    delete tree;
    delete cache;
    delete layout;
    delete file;
    delete dir;
    delete opts.comparator;
}
Ejemplo n.º 2
0
TEST(InnerNode, add_pivot)
{
    Options opts;
    opts.comparator = new LexicalComparator();
    opts.inner_node_children_number = 4;

    Directory *dir = new RAMDirectory();
    AIOFile *file = dir->open_aio_file("tree_test");
    Layout *layout = new Layout(file, 0, opts);
    ASSERT_TRUE(layout->init(true));
    Cache *cache = new Cache(opts);
    ASSERT_TRUE(cache->init());
    Tree *tree = new Tree("", opts, cache, layout);
    ASSERT_TRUE(tree->init());

    InnerNode *n1 = tree->new_inner_node();

    n1->bottom_ = true;
    n1->first_child_ = NID_START + 100;
    n1->first_msgbuf_ = new MsgBuf(opts.comparator);
    n1->msgcnt_ = 0;
    n1->msgbufsz_ = n1->first_msgbuf_->size();

    std::vector<DataNode*> path;

    path.push_back(n1);
    n1->inc_ref();
    n1->write_lock();
    n1->add_pivot("e", NID_START + 101, path);
    EXPECT_EQ(1U, n1->pivots_.size());
    EXPECT_EQ("e", n1->pivots_[0].key);

    path.push_back(n1);
    n1->inc_ref();
    n1->write_lock();
    n1->add_pivot("d", NID_START + 102, path);
    EXPECT_EQ(2U, n1->pivots_.size());
    EXPECT_EQ("d", n1->pivots_[0].key);
    EXPECT_EQ("e", n1->pivots_[1].key);

    path.push_back(n1);
    n1->inc_ref();
    n1->write_lock();
    n1->add_pivot("f", NID_START + 103, path);
    EXPECT_EQ(3U, n1->pivots_.size());
    EXPECT_EQ("d", n1->pivots_[0].key);
    EXPECT_EQ("e", n1->pivots_[1].key);
    EXPECT_EQ("f", n1->pivots_[2].key);

    n1->dec_ref();

    delete tree;
    delete cache;
    delete layout;
    delete file;
    delete dir;
    delete opts.comparator;
}
Ejemplo n.º 3
0
TEST(Tree, bootstrap)
{
    Options opts;
    opts.comparator = new LexicalComparator();
    opts.inner_node_msg_count = 4;
    opts.inner_node_children_number = 2;
    opts.leaf_node_record_count = 4;

    Directory *dir = new RAMDirectory();
    AIOFile *file = dir->open_aio_file("tree_test");
    Layout *layout = new Layout(file, 0, opts);
    ASSERT_TRUE(layout->init(true));
    Cache *cache = new Cache(opts);
    ASSERT_TRUE(cache->init());
    Tree *tree = new Tree("", opts, cache, layout);
    ASSERT_TRUE(tree->init());
    
    InnerNode *n1 = tree->root_;
    EXPECT_EQ(NID_START, n1->nid_);
    
    // the first msgbuf is created
    n1->put("a", "1");
    n1->put("b", "1");
    n1->put("c", "1");
    EXPECT_EQ(NID_NIL, n1->first_child_);
    EXPECT_EQ(3U, n1->first_msgbuf_->count());
    n1->put("d", "1");
    // limit of the first msg reached
    // create leaf#1
    EXPECT_EQ(0U, n1->first_msgbuf_->count());
    EXPECT_TRUE(n1->first_child_ != NID_NIL);
    LeafNode *l1 = (LeafNode*)tree->load_node(n1->first_child_, false);
    EXPECT_EQ(NID_LEAF_START, l1->nid_);
    EXPECT_EQ(4U, l1->records_.size());
    CHK_REC(l1->records_[0], "a", "1");
    CHK_REC(l1->records_[1], "b", "1");
    CHK_REC(l1->records_[2], "c", "1");
    CHK_REC(l1->records_[3], "d", "1");
    
    // go on filling leaf#1's msgbuf
    n1->put("e", "1");
    n1->put("f", "1");
    n1->put("g", "1");
    EXPECT_EQ(3U, n1->first_msgbuf_->count());
    
    n1->put("h", "1");
    // cascading into #leaf1, and split into two leafs
    EXPECT_EQ(0U, n1->first_msgbuf_->count());
    EXPECT_EQ(l1->nid_, n1->first_child_);
    EXPECT_EQ(1U, n1->pivots_.size());
    EXPECT_TRUE(n1->pivots_[0].key == "e");
    EXPECT_TRUE(n1->pivots_[0].child != NID_NIL);
    EXPECT_TRUE(n1->pivots_[0].msgbuf != NULL);
    LeafNode *l2 = (LeafNode*)tree->load_node(n1->pivots_[0].child, false);
    EXPECT_EQ(NID_LEAF_START+1, l2->nid_);
    EXPECT_EQ(4U, l1->records_.size());
    CHK_REC(l1->records_[0], "a", "1");
    CHK_REC(l1->records_[1], "b", "1");
    CHK_REC(l1->records_[2], "c", "1");
    CHK_REC(l1->records_[3], "d", "1");
    EXPECT_EQ(4U, l2->records_.size());
    CHK_REC(l2->records_[0], "e", "1");
    CHK_REC(l2->records_[1], "f", "1");
    CHK_REC(l2->records_[2], "g", "1");
    CHK_REC(l2->records_[3], "h", "1");
    
    n1->put("a", "2");
    n1->put("b", "2");
    n1->put("bb", "1");
    EXPECT_EQ(92U, n1->size());

    n1->put("e", "2");
    
    // cascade into #leaf1 and force leaf#1 split,
    // then propogate to node#1 and generate new root
    
    // node#3(the new root)
    EXPECT_NE(tree->root_, n1);
    InnerNode *n3 = tree->root_;
    EXPECT_EQ(NID_START+2, n3->nid_);
    EXPECT_EQ(n3->first_child_, n1->nid_);
    EXPECT_EQ(n3->first_msgbuf_->count(), 0U);
    
    // node#1
    EXPECT_EQ(0U, n1->first_msgbuf_->count());
    EXPECT_EQ(l1->nid_, n1->first_child_);
    EXPECT_EQ(1U, n1->pivots_.size());
    EXPECT_TRUE(n1->pivots_[0].key == "bb");
    EXPECT_TRUE(n1->pivots_[0].child != NID_NIL);
    EXPECT_TRUE(n1->pivots_[0].child != l2->nid_);
    EXPECT_TRUE(n1->pivots_[0].msgbuf != NULL);
    LeafNode *l3 = (LeafNode*)tree->load_node(n1->pivots_[0].child, false);
    EXPECT_EQ(NID_LEAF_START+2, l3->nid_);
    EXPECT_EQ(2U, l1->records_.size());
    CHK_REC(l1->records_[0], "a", "2");
    CHK_REC(l1->records_[1], "b", "2");
    EXPECT_EQ(3U, l3->records_.size());
    CHK_REC(l3->records_[0], "bb", "1");
    CHK_REC(l3->records_[1], "c", "1");
    CHK_REC(l3->records_[2], "d", "1");
    EXPECT_EQ(59U, n1->size());
    
    // node#2
    EXPECT_EQ(n3->pivots_.size(), 1U);
    EXPECT_TRUE(n3->pivots_[0].key == "e");
    EXPECT_TRUE(n3->pivots_[0].child != NID_NIL);
    InnerNode *n2 = (InnerNode*)tree->load_node(n3->pivots_[0].child, false);
    EXPECT_EQ(NID_START+1, n2->nid_);
    EXPECT_EQ(1U, n2->first_msgbuf_->count());
    CHK_MSG(n2->first_msgbuf_->get(0),  Put, "e", "2");
    EXPECT_EQ(l2->nid_, n2->first_child_);
    EXPECT_EQ(0U, n2->pivots_.size());
    EXPECT_EQ(40U, n2->size());
    
    n3->put("abc", "1");
    n3->put("bb", "2");
    n3->put("ee", "1");
    n3->put("f", "2");
    // cascading down, no split
    EXPECT_EQ(tree->root_, n3);
    EXPECT_EQ(NID_START+2, n3->nid_);
    EXPECT_EQ(n3->first_child_, n1->nid_);
    EXPECT_EQ(0U, n3->first_msgbuf_->count());
    EXPECT_EQ(n3->pivots_[0].child, n2->nid_);
    EXPECT_EQ(2U, n3->pivots_[0].msgbuf->count());
    CHK_MSG(n3->pivots_[0].msgbuf->get(0), Put, "ee", "1");
    CHK_MSG(n3->pivots_[0].msgbuf->get(1), Put, "f", "2");
    
    EXPECT_EQ(1U, n1->first_msgbuf_->count());
    CHK_MSG(n1->first_msgbuf_->get(0), Put, "abc", "1");
    EXPECT_EQ(1U, n1->pivots_[0].msgbuf->count());
    CHK_MSG(n1->pivots_[0].msgbuf->get(0), Put, "bb", "2");

    n3->put("abcd", "1");
    n3->put("g", "2");
    // l2 split
    EXPECT_TRUE(tree->root_ == n3);
    EXPECT_EQ(NID_START+2, n3->nid_);
    EXPECT_TRUE(n3->first_child_ == n1->nid_);
    EXPECT_EQ(1U, n3->first_msgbuf_->count());
    CHK_MSG(n3->first_msgbuf_->get(0), Put, "abcd", "1");
    EXPECT_TRUE(n3->pivots_[0].child == n2->nid_);
    EXPECT_EQ(0U, n3->pivots_[0].msgbuf->count());
    
    EXPECT_EQ(1U, n2->pivots_.size());
    EXPECT_TRUE(n2->first_child_ == l2->nid_);
    EXPECT_EQ(0U, n2->first_msgbuf_->count());
    EXPECT_TRUE(n2->pivots_[0].child != NID_NIL);
    EXPECT_EQ("f", n2->pivots_[0].key);
    EXPECT_EQ(0U, n2->pivots_[0].msgbuf->count());
    LeafNode *l4 = (LeafNode*)tree->load_node(n2->pivots_[0].child, false);
    EXPECT_EQ(NID_LEAF_START+3, l4->nid_);
    EXPECT_EQ(2U, l2->records_.size());
    CHK_REC(l2->records_[0], "e", "2");
    CHK_REC(l2->records_[1], "ee", "1");
    EXPECT_EQ(3U, l4->records_.size());
    CHK_REC(l4->records_[0], "f", "2");
    CHK_REC(l4->records_[1], "g", "2");
    CHK_REC(l4->records_[2], "h", "1");
    
    l1->dec_ref();
    l2->dec_ref();
    l3->dec_ref();
    l4->dec_ref();

    n2->dec_ref();

    delete tree;
    delete cache;
    delete layout;
    delete file;
    delete dir;
    delete opts.comparator;
}