/* * * 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); }
/* * EFFECT: * - alloc ptrs with nonleaf or leaf * REQUIRE: * - node has height * - node has n_children */ void node_ptrs_alloc(struct node *node) { int i; for (i = 0; i < node->n_children; i++) { struct child_pointer *ptr = &node->parts[i].ptr; if (node->height > 0) ptr->u.nonleaf = create_nonleaf(); else ptr->u.leaf = create_leaf(); } }
/* * +-----------------------------------------------+ * | 5 | 7 | 9 | * +-----------------------------------------------+ * | * +---------------+ * | 60 | 61 | 62 | * +---------------+ * * +---------------------------------------------------------------+ * | 5 | 60 | 7 | 9 | * +---------------------------------------------------------------+ * | | * +--------+ +---------+ * | 60 | | 61 | 62 | * +--------+ +---------+ * * * ENTER: * - node is already locked(L_WRITE) * EXITS: * - a is locked(L_WRITE) * - b is locked(L_WRITE) */ static void _node_split(struct tree *t, struct node *node, struct node **a, struct node **b, struct msg **split_key) { int i; int pivots_old; int pivots_in_a; int pivots_in_b; struct node *nodea; struct node *nodeb; struct msg *spk; __DEBUG("nonleaf split begin, NID %"PRIu64"" ", nodesz %d" ", nodec %d" ", children %d" , node->nid , node_size(node) , node_count(node) , node->n_children); nodea = node; pivots_old = node->n_children - 1; nassert(pivots_old > 2); pivots_in_a = pivots_old / 2; pivots_in_b = pivots_old - pivots_in_a; /* node a */ nodea->n_children = pivots_in_a + 1; /* node b */ NID nid = hdr_next_nid(t->hdr); node_create_light(nid, node->height > 0 ? 1 : 0, pivots_in_b + 1, t->hdr->version, t->e, &nodeb); cache_put_and_pin(t->cf, nid, nodeb); for (i = 0; i < (pivots_in_b); i++) nodeb->pivots[i] = nodea->pivots[pivots_in_a + i]; for (i = 0; i < (pivots_in_b + 1); i++) nodeb->parts[i] = nodea->parts[pivots_in_a + i]; /* the rightest partition of nodea */ struct child_pointer *ptr = &nodea->parts[pivots_in_a].ptr; if (nodea->height > 0) ptr->u.nonleaf = create_nonleaf(t->e); else ptr->u.leaf = create_leaf(t->e); /* split key */ spk = msgdup(&node->pivots[pivots_in_a - 1]); node_set_dirty(nodea); node_set_dirty(nodeb); __DEBUG("nonleaf split end, nodea NID %"PRIu64"" ", nodesz %d" ", nodec %d" ", children %d" , nodea->nid , node_size(nodea) , node_count(nodea) , nodea->n_children); __DEBUG("nonleaf split end, nodeb NID %"PRIu64"" ", nodesz %d" ", nodec %d" ", children %d" , nodeb->nid , node_size(nodeb) , node_count(nodeb) , nodeb->n_children); *a = nodea; *b = nodeb; *split_key = spk; }