Пример #1
0
/*
 * 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);
	}
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
/*
 * 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;
}