Beispiel #1
0
CTEST(basement, empty)
{
	int ret;
	struct basement_iter iter;
	struct basement *bsm = basement_new();

	basement_iter_init(&iter, bsm);
	basement_iter_seektofirst(&iter);
	ret = basement_iter_valid(&iter);
	ASSERT_EQUAL(0, ret);

	struct msg m1 = {
		.size = 6,
		.data = "key-01"
	};

	basement_iter_seek(&iter, &m1);
	ret = basement_iter_valid(&iter);
	ASSERT_EQUAL(0, ret);

	basement_free(bsm);
	xcheck_all_free();
}

void _random_key(char *key,int length) {
	int i;
	char salt[36]= "abcdefghijklmnopqrstuvwxyz123456789";

	for (i = 0; i < length; i++)
		key[i] = salt[rand() % 36];
}
Beispiel #2
0
CTEST(basement, insert_and_lookup)
{
	int i;
	int ret;
	int R = 1000;
	char kbuf[KEY_SIZE];
	char vbuf[VAL_SIZE];
	struct basement_iter iter;
	struct basement *bsm = basement_new();
	struct msg **msgs = xcalloc(R, sizeof(*msgs));
	struct txnid_pair xidpair =  {
		.child_xid = TXNID_NONE,
		.parent_xid = TXNID_NONE
	};

	MSN msn = 0U;

	_random_key(vbuf, VAL_SIZE);
	for (i = 0; i < R; i++) {
		memset(kbuf, 0, KEY_SIZE);
		snprintf(kbuf, KEY_SIZE, "key-%d", i);

		struct msg k = {.data = kbuf, .size = KEY_SIZE};
		struct msg v = {.data = vbuf, .size = VAL_SIZE};

		msgs[i] = msgdup(&k);
		basement_put(bsm,
		             msn++,
		             MSG_INSERT,
		             &k,
		             &v,
		             &xidpair
		            );
	}

	basement_iter_init(&iter, bsm);
	basement_iter_seektolast(&iter);
	ret = basement_iter_valid(&iter);
	ASSERT_EQUAL(1, ret);

	for (i = 0; i < R; i++) {
		basement_iter_seek(&iter, msgs[i]);
		ret = basement_iter_valid(&iter);
		ASSERT_EQUAL(1, ret);
		ret = msg_key_compare(msgs[i], &iter.key);
		ASSERT_EQUAL(0, ret);
	}

	/* do msg free */
	for (i = 0; i < R; i++) {
		xfree(msgs[i]->data);
		xfree(msgs[i]);
	}
	xfree(msgs);

	basement_free(bsm);
	xcheck_all_free();
}
Beispiel #3
0
int _findsmallest(struct basement **bsms,
		int bsms_size,
		struct cursor *cur,
		struct search *so)
{
	int i;
	int ret;
	int end;
	struct basement_iter *smallest = NULL;
	struct basement_iter iters[bsms_size];
	
	/* seek each level */
	for (i = (bsms_size - 1); i >= 0; i--) {
		struct basement *bsm;
		struct basement_iter *iter;
		
		bsm = bsms[i];
		iter = &iters[i];
		basement_iter_init(iter, bsm);
		if (so->key) {
			/*
			 * sought position is >= position(so->key)
			 * so we should ensure that all sought iters positioned after so->key
			 */
			basement_iter_seek(iter, so->key);
			if (so->slip != SLIP_ZERO) {
				if (basement_iter_valid(iter) &&
						(so->key_compare_func(&iter->key, so->key) == 0))
					basement_iter_next(iter);
			}
		} else {
			basement_iter_seektofirst(iter);
		}
	}

	for (i = (bsms_size - 1); i >= 0; i--) {
		struct basement_iter *iter = &iters[i];

		if (basement_iter_valid(iter)) {
			if (smallest == NULL) {
				smallest = iter;
			} else if (so->key_compare_func(&iter->key, &smallest->key) < 0) {
				smallest = iter;
			}
		}
	}

	end = (basement_iter_valid(&iters[0]) == 0);
	if (end) {
		if (smallest) {
			cur->valid = 1;
			cur->key = smallest->key;
			cur->val = smallest->val;
		} else {
			cur->valid = 0;
		}

		ret = CURSOR_EOF;
	} else {
		cur->valid = 1;
		cur->key = smallest->key;
		cur->val = smallest->val;
		ret = CURSOR_CONTINUE;
	}

	return ret;
}
Beispiel #4
0
int _findlargest(struct basement **bsms,
		int bsms_size,
		struct cursor *cur,
		struct search *so)
{
	int i;
	int ret;
	int end;
	struct basement_iter *largest = NULL;
	struct basement_iter iters[bsms_size];
	
	/* seek each level */
	for (i = (bsms_size - 1); i >= 0; i--) {
		struct basement *bsm;
		struct basement_iter *iter;
		
		bsm = bsms[i];
		iter = &iters[i];
		basement_iter_init(iter, bsm);
		if (so->key) {
			/*
			 * since basement_iter_seek is >=so->key,
			 * we should ensure that all sought iters positioned before so->key
			 */
			basement_iter_seek(iter, so->key);
			if (basement_iter_valid(iter))
				basement_iter_prev(iter);
			else
				basement_iter_seektolast(iter);
		} else {
			basement_iter_seektolast(iter);
		}
	}

	for (i = (bsms_size - 1); i >= 0; i--) {
		struct basement_iter *iter = &iters[i];

		if (basement_iter_valid(iter)) {
			if (largest == NULL) {
				largest = iter;
			} else if (so->key_compare_func(&iter->key, &largest->key) > 0) {
				largest = iter;
			}
		}
	}

	end = (basement_iter_valid(&iters[0]) == 0);
	if (end) {
		if (largest) {
			cur->valid = 1;
			cur->key = largest->key;
			cur->val = largest->val;
		} else
			cur->valid = 0;

		ret = CURSOR_EOF;
	} else {
		cur->valid = 1;
		cur->key = largest->key;
		cur->val = largest->val;
		ret = CURSOR_CONTINUE;
	}

	return ret;
}
Beispiel #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;
}
Beispiel #6
0
CTEST(node_serial_test, node_2th_part_empty)
{
	int ret = 0;
	NID nid;
	uint32_t n_children = 3;
	int fd = ness_os_open(BRT_FILE, O_RDWR | O_CREAT, 0777);
	struct block *b = block_new();
	struct hdr *hdr = (struct hdr*)xcalloc(1, sizeof(*hdr));
	struct options *opts = options_new();

	/*
	 * serialize
	 */
	struct node *dummy_node;

	hdr->last_nid++;
	nid = hdr->last_nid;
	dummy_node = nonleaf_alloc_empty(nid, 1, n_children);
	nonleaf_alloc_buffer(dummy_node);

	struct msg p0;
	p0.size = 6;
	p0.data = "pivot0";
	msgcpy(&dummy_node->u.n.pivots[0], &p0);

	struct msg p1;
	p1.size = 6;
	p1.data = "pivot1";
	msgcpy(&dummy_node->u.n.pivots[1], &p1);

	MSN msn = 0U;
	struct xids *xids = NULL;
	struct msg k, v;
	k.size = 5;
	k.data = "hello";
	v.size = 5;
	v.data = "world";
	basement_put(dummy_node->u.n.parts[0].buffer, &k, &v, MSG_INSERT, msn,
	             xids);


	hdr->method = NESS_QUICKLZ_METHOD;
	ret = serialize_node_to_disk(fd, b, dummy_node, hdr);
	ASSERT_TRUE(ret > 0);
	node_free(dummy_node);

	//deserialize
	int light = 0;
	struct node *dummy_node1;
	ret = deserialize_node_from_disk(fd, b, nid, &dummy_node1, light);
	ASSERT_TRUE(ret > 0);

	ASSERT_EQUAL(1, dummy_node1->height);
	ASSERT_EQUAL(3, dummy_node1->u.n.n_children);
	ASSERT_DATA((const unsigned char*)"pivot0",
	            6,
	            (const unsigned char*)dummy_node1->u.n.pivots[0].data,
	            dummy_node1->u.n.pivots[0].size);

	ASSERT_DATA((const unsigned char*)"pivot1",
	            6,
	            (const unsigned char*)dummy_node1->u.n.pivots[1].data,
	            dummy_node1->u.n.pivots[1].size);
	ASSERT_EQUAL(3, dummy_node1->u.n.n_children);

	if (!light) {
		int cmp;
		struct basement_iter iter;
		struct basement *bsm;

		bsm = dummy_node1->u.n.parts[0].buffer;
		basement_iter_init(&iter, bsm);

		int mb_c = basement_count(dummy_node1->u.n.parts[0].buffer);
		ASSERT_EQUAL(1, mb_c);
		basement_iter_seek(&iter, &k);
		ret = basement_iter_valid(&iter);
		ASSERT_EQUAL(1, ret);
		cmp = msg_key_compare(&k, &iter.key);
		ASSERT_EQUAL(0, cmp);
		cmp = msg_key_compare(&v, &iter.val);
		ASSERT_EQUAL(0, cmp);

		mb_c = basement_count(dummy_node1->u.n.parts[1].buffer);
		ASSERT_EQUAL(0, mb_c);
	}
	node_free(dummy_node1);

	ness_os_close(fd);
	block_free(b);
	xfree(hdr);
	options_free(opts);
	xcheck_all_free();
}
Beispiel #7
0
CTEST(basement, multiversion)
{
	int i;
	int ret;
	int R = 123;
	char kbuf[KEY_SIZE];
	char vbuf[VAL_SIZE];
	struct basement_iter iter;
	struct basement *bsm = basement_new();
	struct txnid_pair xidpair =  {
		.child_xid = TXNID_NONE,
		.parent_xid = TXNID_NONE
	};

	_random_key(vbuf, VAL_SIZE);

	MSN msn = 0U;
	for (i = 0; i < R; i++) {
		memset(kbuf, 0, KEY_SIZE);
		snprintf(kbuf, KEY_SIZE, "key-%d", i);

		struct msg k = {.data = kbuf, .size = KEY_SIZE};
		struct msg v = {.data = vbuf, .size = VAL_SIZE};

		basement_put(bsm,
		             msn++,
		             MSG_INSERT,
		             &k,
		             &v,
		             &xidpair
		            );
	}

	/* 3 versions of key-66 */
	R = 3;
	for (i = 0; i < R; i++) {
		memset(kbuf, 0, KEY_SIZE);
		snprintf(kbuf, KEY_SIZE, "key-66");

		struct msg k = {.data = kbuf, .size = KEY_SIZE};
		struct msg v = {.data = vbuf, .size = VAL_SIZE};

		basement_put(bsm,
		             msn++,
		             MSG_INSERT,
		             &k,
		             &v,
		             &xidpair
		            );
	}

	/* 5 versions of key-88 */
	R = 5;
	for (i = 0; i < R; i++) {
		memset(kbuf, 0, KEY_SIZE);
		snprintf(kbuf, KEY_SIZE, "key-88");

		struct msg k = {.data = kbuf, .size = KEY_SIZE};
		struct msg v = {.data = vbuf, .size = VAL_SIZE};

		basement_put(bsm,
		             msn++,
		             MSG_INSERT,
		             &k,
		             &v,
		             &xidpair
		            );
	}

	/* key-66 */
	memset(kbuf, 0, KEY_SIZE);
	snprintf(kbuf, KEY_SIZE, "key-66");

	struct msg k1 = {.data = kbuf, .size = KEY_SIZE};
	basement_iter_init(&iter, bsm);
	basement_iter_seek(&iter, &k1);
	ret = basement_iter_valid(&iter);
	ASSERT_EQUAL(1, ret);
	ASSERT_EQUAL(66, iter.msn);

	basement_iter_next(&iter);
	ret = basement_iter_valid(&iter);
	ASSERT_EQUAL(1, ret);
	ASSERT_EQUAL(123, iter.msn);

	/* less than valid */
	ret = basement_iter_valid_lessorequal(&iter, &k1);
	ASSERT_EQUAL(1, ret);

	memset(kbuf, 0, KEY_SIZE);
	snprintf(kbuf, KEY_SIZE, "key-67");
	k1.size = KEY_SIZE;
	k1.data = kbuf;
	ret = basement_iter_valid_lessorequal(&iter, &k1);
	ASSERT_EQUAL(1, ret);

	memset(kbuf, 0, KEY_SIZE);
	snprintf(kbuf, KEY_SIZE, "key-65");
	k1.size = KEY_SIZE;
	k1.data = kbuf;
	ret = basement_iter_valid_lessorequal(&iter, &k1);
	ASSERT_EQUAL(0, ret);

	/* key-88 */
	memset(kbuf, 0, KEY_SIZE);
	snprintf(kbuf, KEY_SIZE, "key-88");

	struct msg k2 = {.data = kbuf, .size = KEY_SIZE};
	basement_iter_seek(&iter, &k2);
	ret = basement_iter_valid(&iter);
	ASSERT_EQUAL(1, ret);
	ASSERT_EQUAL(88, iter.msn);

	basement_iter_next(&iter);
	basement_iter_next(&iter);
	ret = basement_iter_valid(&iter);
	ASSERT_EQUAL(1, ret);
	ASSERT_EQUAL(127, iter.msn);

	/* next&prev diff key */
	/* key-87 */
	memset(kbuf, 0, KEY_SIZE);
	snprintf(kbuf, KEY_SIZE, "key-87");

	struct msg k3 = {.data = kbuf, .size = KEY_SIZE};
	basement_iter_prev_diff_key(&iter);
	ret = msg_key_compare(&k3, &iter.key);
	ASSERT_EQUAL(0, ret);

	/* key-88 */
	basement_iter_next(&iter);
	memset(kbuf, 0, KEY_SIZE);
	snprintf(kbuf, KEY_SIZE, "key-88");
	struct msg k22 = {.data = kbuf, .size = KEY_SIZE};
	ret = msg_key_compare(&k22, &iter.key);
	ASSERT_EQUAL(0, ret);

	/* key-89 */
	memset(kbuf, 0, KEY_SIZE);
	snprintf(kbuf, KEY_SIZE, "key-89");

	struct msg k4 = {.data = kbuf, .size = KEY_SIZE};
	basement_iter_next_diff_key(&iter);
	ret = msg_key_compare(&k4, &iter.key);
	ASSERT_EQUAL(0, ret);

	basement_free(bsm);
	xcheck_all_free();
}