Example #1
0
void nmb_to_msgpack(struct nmb  *nmb, struct msgpack *packer)
{
	struct mb_iter iter;

	mb_iter_init(&iter, nmb->pma);
	while (mb_iter_next(&iter)) {
		struct nmb_values values;

		nmb_get_values(&iter, &values);
		nmb_pack_values_to_msgpack(&values, packer);
	}
}
Example #2
0
/*
 * apply parent's (left, right] messages to child node
 */
void leaf_apply(struct node *leaf,
                struct nmb *msgbuf,
                struct msg *left,
                struct msg *right)
{
	struct mb_iter iter;
	struct pma_coord coord_left;
	struct pma_coord coord_right;

	nmb_get_left_coord(msgbuf, left, &coord_left);
	nmb_get_right_coord(msgbuf, right, &coord_right);

	mb_iter_init(&iter, msgbuf->pma);
	while (mb_iter_on_range(&iter, &coord_left, &coord_right)) {
		struct nmb_values values;

		nmb_get_values(&iter, &values);

		struct bt_cmd cmd = {
			.msn = values.msn,
			.type = values.type,
			.key = &values.key,
			.val = &values.val,
			.xidpair = values.xidpair
		};

		if (cmd.msn > leaf->msn) {
			leaf_put(leaf, &cmd);
		}
	}
}

int leaf_find_heaviest_idx(struct node *leaf)
{
	int i;
	int idx = 0;
	uint32_t sz = 0;
	uint32_t maxsz = 0;

	for (i = 0; i < leaf->n_children; i++) {
		struct lmb *msgbuf = (struct lmb*)&leaf->parts[i].msgbuf;

		sz = lmb_memsize(msgbuf);
		if (sz > maxsz) {
			idx = i;
			maxsz = sz;
		}
	}

	return idx;
}
Example #3
0
void nmb_to_msgpack(void *p, void *n)
{
	struct mb_iter iter;
	struct msgpack *packer = (struct msgpack*)p;
	struct nmb *nmb = (struct nmb*)n;

	mb_iter_init(&iter, nmb->pma);
	while (mb_iter_next(&iter)) {
		struct nmb_values values;

		nmb_get_values(&iter, &values);
		nmb_pack_values_to_msgpack(&values, packer);
	}
}
Example #4
0
void _flush_buffer_to_child(struct tree *t, struct node *child, struct nmb *buf)
{
	struct mb_iter iter;

	mb_iter_init(&iter, buf->pma);
	while (mb_iter_next(&iter)) {
		/* TODO(BohuTANG): check msn */
		struct nmb_values nvalues;

		nmb_get_values(&iter, &nvalues);

		struct bt_cmd cmd = {
			.msn = nvalues.msn,
			.type = nvalues.type,
			.key = &nvalues.key,
			.val = &nvalues.val,
			.xidpair = nvalues.xidpair
		};
		node_put_cmd(t, child, &cmd);
	}
}

void _flush_some_child(struct tree *t, struct node *parent);

/*
 * PROCESS:
 *	- check child reactivity
 *	- if FISSIBLE: split child
 *	- if FLUSHBLE: flush buffer from child
 * ENTER:
 *	- parent is already locked
 *	- child is already locked
 * EXIT:
 *	- parent is unlocked
 *	- no nodes are locked
 */
void _child_maybe_reactivity(struct tree *t, struct node *parent, struct node *child)
{
	enum reactivity re = get_reactivity(t, child);

	switch (re) {
	case STABLE:
		cache_unpin(t->cf, child->cpair, make_cpair_attr(child));
		cache_unpin(t->cf, parent->cpair, make_cpair_attr(parent));
		break;
	case FISSIBLE:
		node_split_child(t, parent, child);
		cache_unpin(t->cf, child->cpair, make_cpair_attr(child));
		cache_unpin(t->cf, parent->cpair, make_cpair_attr(parent));
		break;
	case FLUSHBLE:
		cache_unpin(t->cf, parent->cpair, make_cpair_attr(parent));
		_flush_some_child(t, child);
		break;
	}
}

/*
 * PROCESS:
 *	- pick a heaviest child of parent
 *	- flush from parent to child
 *	- maybe split/flush child recursively
 * ENTER:
 *	- parent is already locked
 * EXIT:
 *	- parent is unlocked
 *	- no nodes are locked
 */
void _flush_some_child(struct tree *t, struct node *parent)
{
	int childnum;
	enum reactivity re;
	struct node *child;
	struct partition *part;
	struct nmb *buffer;
	struct timespec t1, t2;

	childnum = node_find_heaviest_idx(parent);
	nassert(childnum < parent->n_children);
	part = &parent->parts[childnum];
	buffer = part->ptr.u.nonleaf->buffer;
	if (cache_get_and_pin(t->cf, part->child_nid, (void**)&child, L_WRITE) != NESS_OK) {
		__ERROR("cache get node error, nid [%" PRIu64 "]", part->child_nid);
		return;
	}

	ngettime(&t1);
	re = get_reactivity(t, child);
	if (re == STABLE) {
		node_set_dirty(parent);
		part->ptr.u.nonleaf->buffer = nmb_new(t->e);
		_flush_buffer_to_child(t, child, buffer);
		nmb_free(buffer);
	}
	ngettime(&t2);
	status_add(&t->e->status->tree_flush_child_costs, time_diff_ms(t1, t2));
	status_increment(&t->e->status->tree_flush_child_nums);

	_child_maybe_reactivity(t, parent, child);
}