/* * EFFECT: * - put cmd to node * ENTER: * - node is already locked(L_WRITE) * EXITS: * - node is locked */ void node_put_cmd(struct tree *t, struct node *node, struct bt_cmd *cmd) { if (nessunlikely(node->height == 0)) { leaf_put_cmd(node, cmd); status_increment(&t->e->status->tree_leaf_put_nums); } else { nonleaf_put_cmd(node, cmd); status_increment(&t->e->status->tree_nonleaf_put_nums); } }
uint32_t leaf_size(struct node *leaf) { int i; uint32_t sz = 0U; nassert(leaf->n_children == 1); for (i = 0; i < leaf->n_children; i++) { if (nessunlikely(i < (leaf->n_children - 1))) sz += msgsize(&leaf->pivots[i]); sz += sizeof(leaf->parts[i]); sz += lmb_memsize(leaf->parts[i].msgbuf); } sz += sizeof(*leaf); return sz; }
enum reactivity get_reactivity(struct tree *t, struct node *node) { uint32_t children = node->n_children; if (nessunlikely(node->height == 0)) { if (node_size(node) >= t->e->leaf_default_node_size) return FISSIBLE; } else { if (children >= t->e->inner_node_fanout) return FISSIBLE; if (node_size(node) >= t->e->inner_default_node_size) return FLUSHBLE; } return STABLE; }
uint32_t node_size(struct node *n) { uint32_t size = 0U; size += (sizeof(*n)); if (nessunlikely(n->height == 0)) { size += lmb_memsize(n->u.l.buffer); } else { uint32_t i; for (i = 0; i < n->u.n.n_children - 1; i++) { size += msgsize(&n->u.n.pivots[i]); } for (i = 0; i < n->u.n.n_children; i++) { size += nmb_memsize(n->u.n.parts[i].buffer); } } return size; }
/* * apply parent's [leaf, right] messages to child node */ void _apply_msg_to_child(struct node *parent, int child_num, struct node *child, struct msg *left, struct msg *right) { int height; struct basement *bsm; struct basement_iter iter; nassert(child != NULL); nassert(parent->height > 0); height = child->height; if (height == 0) bsm = child->u.l.le->bsm; else bsm = child->u.n.parts[child_num].buffer; basement_iter_init(&iter, bsm); basement_iter_seek(&iter, left); while (basement_iter_valid_lessorequal(&iter, right)) { struct bt_cmd cmd = { .msn = iter.msn, .type = iter.type, .key = &iter.key, .val = &iter.val, .xidpair = iter.xidpair }; if (nessunlikely(height == 0)) leaf_put_cmd(child, &cmd); else nonleaf_put_cmd(child, &cmd); } } /* * apply msgs from ances to leaf basement which are between(include) left and right * REQUIRES: * 1) leaf write-lock * 2) ances all write-lock */ int leaf_apply_ancestors(struct node *leaf, struct ancestors *ances) { struct ancestors *ance; struct msg *left = NULL; struct msg *right = NULL; struct basement_iter iter; struct basement *bsm = leaf->u.l.le->bsm; basement_iter_init(&iter, bsm); basement_iter_seektofirst(&iter); if (basement_iter_valid(&iter)) left = msgdup(&iter.key); basement_iter_seektolast(&iter); if (basement_iter_valid(&iter)) right = msgdup(&iter.key); ance = ances; while (ance && ance->next) { /* apply [leaf, right] to leaf */ _apply_msg_to_child(ance->v, ance->childnum, ance->next->v, left, right); ance = ances->next; } msgfree(left); msgfree(right); return NESS_OK; }