static void _root_split(struct tree *t, struct node *new_root, struct node *old_root) { struct node *a; struct node *b; struct msg *split_key = NULL; __DEBUG("root split begin, old NID %"PRIu64" , height %d" , old_root->nid , old_root->height); if (old_root->height > 0 || old_root->n_children > 2) _node_split(t, old_root, &a, &b, &split_key); else _leaf_and_lmb_split(t, old_root, &a, &b, &split_key); /* swap two roots */ _root_swap(new_root, old_root); msgcpy(&new_root->pivots[0], split_key); new_root->parts[0].child_nid = a->nid; new_root->parts[1].child_nid = b->nid; msgfree(split_key); cache_unpin(t->cf, b->cpair, make_cpair_attr(b)); node_set_dirty(old_root); node_set_dirty(new_root); t->hdr->height++; status_increment(&t->e->status->tree_root_new_nums); __DEBUG("root split end, old NID %"PRIu64, old_root->nid); }
/* * * PROCESS: * - if the layout as follows(3 pivots, 4 partitions): * * +--------+--------+--------+ * | 15 | 17 | 19 | +∞ * +--------+--------+--------+\ * pidx0 pidx1 pidx2 pidx3 * * * - so if spk is 16, pidx = 1, after added(4 pivtos, 5 partitions): * * +--------+--------+--------+--------+ * | 15 | [16] | 17 | 19 | +∞ * +--------+--------+--------+--------+\ * pidx0 [pidx1] pidx2 pidx3 pidx4 * * * ENTER: * - parent is already locked(L_WRITE) * - node a is already locked(L_WRITE) * - node b is already locked(L_WRITE) */ static void _add_pivot_to_parent(struct tree *t, struct node *parent, int child_num, struct node *a, struct node *b, struct msg *spk) { int i; int pidx; struct child_pointer *cptr; pidx = child_num; parent->pivots = xrealloc(parent->pivots, parent->n_children * PIVOT_SIZE); parent->parts = xrealloc(parent->parts, (parent->n_children + 1) * PART_SIZE); /* slide pivots */ for (i = (parent->n_children - 1); i > pidx; i--) parent->pivots[i] = parent->pivots[i - 1]; /* slide parts */ for (i = parent->n_children; i > pidx; i--) parent->parts[i] = parent->parts[i - 1]; /* new part */ msgcpy(&parent->pivots[pidx], spk); parent->parts[pidx].child_nid = a->nid; cptr = &parent->parts[pidx].ptr; cptr->u.nonleaf = create_nonleaf(t->e); parent->parts[pidx + 1].child_nid = b->nid; parent->n_children += 1; node_set_dirty(parent); status_increment(&t->e->status->tree_add_pivots_nums); }
CTEST(node_serial_test, node_2th_part_empty) { int ret = 0; NID nid; uint32_t n_children = 3; int fd = ness_os_open(BRT_FILE, O_RDWR | O_CREAT, 0777); struct block *b = block_new(); struct hdr *hdr = (struct hdr*)xcalloc(1, sizeof(*hdr)); struct options *opts = options_new(); /* * serialize */ struct node *dummy_node; hdr->last_nid++; nid = hdr->last_nid; dummy_node = nonleaf_alloc_empty(nid, 1, n_children); nonleaf_alloc_buffer(dummy_node); struct msg p0; p0.size = 6; p0.data = "pivot0"; msgcpy(&dummy_node->u.n.pivots[0], &p0); struct msg p1; p1.size = 6; p1.data = "pivot1"; msgcpy(&dummy_node->u.n.pivots[1], &p1); MSN msn = 0U; struct xids *xids = NULL; struct msg k, v; k.size = 5; k.data = "hello"; v.size = 5; v.data = "world"; basement_put(dummy_node->u.n.parts[0].buffer, &k, &v, MSG_INSERT, msn, xids); hdr->method = NESS_QUICKLZ_METHOD; ret = serialize_node_to_disk(fd, b, dummy_node, hdr); ASSERT_TRUE(ret > 0); node_free(dummy_node); //deserialize int light = 0; struct node *dummy_node1; ret = deserialize_node_from_disk(fd, b, nid, &dummy_node1, light); ASSERT_TRUE(ret > 0); ASSERT_EQUAL(1, dummy_node1->height); ASSERT_EQUAL(3, dummy_node1->u.n.n_children); ASSERT_DATA((const unsigned char*)"pivot0", 6, (const unsigned char*)dummy_node1->u.n.pivots[0].data, dummy_node1->u.n.pivots[0].size); ASSERT_DATA((const unsigned char*)"pivot1", 6, (const unsigned char*)dummy_node1->u.n.pivots[1].data, dummy_node1->u.n.pivots[1].size); ASSERT_EQUAL(3, dummy_node1->u.n.n_children); if (!light) { int cmp; struct basement_iter iter; struct basement *bsm; bsm = dummy_node1->u.n.parts[0].buffer; basement_iter_init(&iter, bsm); int mb_c = basement_count(dummy_node1->u.n.parts[0].buffer); ASSERT_EQUAL(1, mb_c); basement_iter_seek(&iter, &k); ret = basement_iter_valid(&iter); ASSERT_EQUAL(1, ret); cmp = msg_key_compare(&k, &iter.key); ASSERT_EQUAL(0, cmp); cmp = msg_key_compare(&v, &iter.val); ASSERT_EQUAL(0, cmp); mb_c = basement_count(dummy_node1->u.n.parts[1].buffer); ASSERT_EQUAL(0, mb_c); } node_free(dummy_node1); ness_os_close(fd); block_free(b); xfree(hdr); options_free(opts); xcheck_all_free(); }