Exemple #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);
	}
}
Exemple #2
0
/*
 * EFFECTS:
 *	- iterate the pma with range[left, right)
 * RETURNS:
 *	- 0 means invalid
 *	- 1 means valid
 */
int mb_iter_on_range(struct mb_iter *iter,
                     struct pma_coord *left,
                     struct pma_coord *right)
{
	int cur_idx = iter->slot_idx + iter->array_idx;
	int min_idx = left->slot_idx + left->array_idx;
	int max_idx = right->slot_idx + right->array_idx;

	if (cur_idx >= min_idx && cur_idx < max_idx)
		return mb_iter_next(iter);
	else
		return 0;
}
Exemple #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);
	}
}
Exemple #4
0
int _search_leaf(struct cursor *cur, struct search *so, struct node *leaf)
{
	int found;
	int ret = CURSOR_EOF;
	struct lmb *lmb;
	struct mb_iter iter;
	struct leafentry *le;
	struct pma_coord coord;

	/* 1) apply all msgs to leaf msgbuf */
	//leaf_apply_ancestors(leaf, cur->ances);

	/* 2) init leaf iterator, TODO: which msgbuf to read */
	lmb = leaf->parts[0].msgbuf;
	mb_iter_init(&iter, lmb->pma);

	/* 3) do search */
	switch (so->gap) {
	case GAP_ZERO:
		found = lmb_find_zero(lmb, &cur->key, &le, &coord);
		if (found) {
			mb_iter_reset(&iter, &coord);
			if (mb_iter_valid(&iter)) {
				_cursor_get_values_from_leafentry(cur, iter.base);
			}
		}
		ret = CURSOR_EOF;
		break;
	case GAP_POSI:
		found = lmb_find_plus(lmb, &cur->key, &le, &coord);
		if (found) {
			mb_iter_reset(&iter, &coord);
POSI_RETRY:
			if (mb_iter_valid(&iter)) {
				int got = _cursor_get_values_from_leafentry(cur, iter.base);
				if (!got) {
					mb_iter_next(&iter);
					goto POSI_RETRY;
				} else {
					ret = CURSOR_EOF;
				}
			} else {
				ret = CURSOR_CONTINUE;
			}
		}
		break;
	case GAP_NEGA:
		found = lmb_find_minus(lmb, &cur->key, &le, &coord);
		if (found) {
			mb_iter_reset(&iter, &coord);
NEGA_RETRY:
			if (mb_iter_valid(&iter)) {
				int got = _cursor_get_values_from_leafentry(cur, iter.base);
				if (!got) {
					mb_iter_prev(&iter);
					goto NEGA_RETRY;
				} else {
					ret = CURSOR_EOF;
				}
			} else {
				ret = CURSOR_CONTINUE;
			}
		}
		break;
	}

	return ret;
}
Exemple #5
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);
}