Esempio n. 1
0
/*
 * col_insert --
 *	Insert an element in a column-store file.
 */
static void
col_insert(WT_CURSOR *cursor, WT_ITEM *key, WT_ITEM *value, uint64_t *keynop)
{
	WT_SESSION *session;
	uint64_t keyno;
	int notfound, ret;

	session = cursor->session;

	value_gen((uint8_t *)value->data, &value->size, g.rows + 1);

	if (g.c_file_type == FIX)
		cursor->set_value(cursor, *(uint8_t *)value->data);
	else
		cursor->set_value(cursor, value);
	if ((ret = cursor->insert(cursor)) != 0)
		die(ret, "cursor.insert");
	if ((ret = cursor->get_key(cursor, &keyno)) != 0)
		die(ret, "cursor.get_key");
	*keynop = (uint32_t)keyno;

	/*
	 * Assign the maximum number of rows to the returned key: that key may
	 * not be the current maximum value, if we race with another thread,
	 * but that's OK, we just want it to keep increasing so we don't ignore
	 * records at the end of the table.
	 */
	g.rows = (uint32_t)keyno;

	if (g.logging == LOG_OPS) {
		if (g.c_file_type == FIX)
			(void)session->msg_printf(session,
			    "%-10s%" PRIu64 " {0x%02" PRIx8 "}",
			    "insert", keyno,
			    ((uint8_t *)value->data)[0]);
		else
			(void)session->msg_printf(session,
			    "%-10s%" PRIu64 " {%.*s}",
			    "insert", keyno,
			    (int)value->size, (char *)value->data);
	}

	if (!SINGLETHREADED)
		return;

	key_gen((uint8_t *)key->data, &key->size, keyno, 0);
	bdb_update(key->data, key->size, value->data, value->size, &notfound);
}
Esempio n. 2
0
/*
 * col_remove --
 *	Remove a row from a column-store file.
 */
static void
col_remove(WT_CURSOR *cursor, WT_ITEM *key, uint64_t keyno, int *notfoundp)
{
	WT_SESSION *session;
	int notfound, ret;

	session = cursor->session;

	/* Log the operation */
	if (g.logging == LOG_OPS)
		(void)session->msg_printf(
		    session, "%-10s%" PRIu64, "remove", keyno);

	cursor->set_key(cursor, keyno);
	ret = cursor->remove(cursor);
	if (ret != 0 && ret != WT_NOTFOUND)
		die(ret, "col_remove: remove %" PRIu64 " by key", keyno);
	*notfoundp = ret == WT_NOTFOUND;

	if (!SINGLETHREADED)
		return;

	/*
	 * Deleting a fixed-length item is the same as setting the bits to 0;
	 * do the same thing for the BDB store.
	 */
	if (g.c_file_type == FIX) {
		key_gen((uint8_t *)key->data, &key->size, keyno, 0);
		bdb_update(key->data, key->size, "\0", 1, &notfound);
	} else
		bdb_remove(keyno, &notfound);

	(void)notfound_chk("col_remove", ret, notfound, keyno);
}
Esempio n. 3
0
/*
 * row_remove --
 *	Remove an row from a row-store file.
 */
static void
row_remove(WT_CURSOR *cursor, WT_ITEM *key, uint64_t keyno, int *notfoundp)
{
	WT_SESSION *session;
	int notfound, ret;

	session = cursor->session;

	key_gen((uint8_t *)key->data, &key->size, keyno, 0);

	/* Log the operation */
	if (g.logging == LOG_OPS)
		(void)session->msg_printf(
		    session, "%-10s%" PRIu64, "remove", keyno);

	cursor->set_key(cursor, key);
	ret = cursor->remove(cursor);
	if (ret != 0 && ret != WT_NOTFOUND)
		die(ret, "row_remove: remove %" PRIu64 " by key", keyno);
	*notfoundp = ret == WT_NOTFOUND;

	if (!SINGLETHREADED)
		return;

	bdb_remove(keyno, &notfound);
	(void)notfound_chk("row_remove", ret, notfound, keyno);
}
Esempio n. 4
0
/*
 * row_update --
 *	Update a row in a row-store file.
 */
static void
row_update(
    WT_CURSOR *cursor, WT_ITEM *key, WT_ITEM *value, uint64_t keyno, int insert)
{
	WT_SESSION *session;
	int notfound, ret;

	session = cursor->session;

	key_gen((uint8_t *)key->data, &key->size, keyno, insert);
	value_gen((uint8_t *)value->data, &value->size, keyno);

	/* Log the operation */
	if (g.logging == LOG_OPS)
		(void)session->msg_printf(session, "%-10s{%.*s}\n%-10s{%.*s}",
		    insert ? "insertK" : "putK",
		    (int)key->size, (char *)key->data,
		    insert ? "insertV" : "putV",
		    (int)value->size, (char *)value->data);

	cursor->set_key(cursor, key);
	cursor->set_value(cursor, value);
	ret = cursor->insert(cursor);
	if (ret != 0 && ret != WT_NOTFOUND)
		die(ret,
		    "row_update: %s row %" PRIu64 " by key",
		    insert ? "insert" : "update", keyno);

	if (!SINGLETHREADED)
		return;

	bdb_update(key->data, key->size, value->data, value->size, &notfound);
	(void)notfound_chk("row_update", ret, notfound, keyno);
}
Esempio n. 5
0
/*
 * col_update --
 *	Update a row in a column-store file.
 */
static void
col_update(WT_CURSOR *cursor, WT_ITEM *key, WT_ITEM *value, uint64_t keyno)
{
	WT_SESSION *session;
	int notfound, ret;

	session = cursor->session;

	value_gen((uint8_t *)value->data, &value->size, keyno);

	/* Log the operation */
	if (g.logging == LOG_OPS) {
		if (g.c_file_type == FIX)
			(void)session->msg_printf(session,
			    "%-10s%" PRIu64 " {0x%02" PRIx8 "}",
			    "update", keyno,
			    ((uint8_t *)value->data)[0]);
		else
			(void)session->msg_printf(session,
			    "%-10s%" PRIu64 " {%.*s}",
			    "update", keyno,
			    (int)value->size, (char *)value->data);
	}

	cursor->set_key(cursor, keyno);
	if (g.c_file_type == FIX)
		cursor->set_value(cursor, *(uint8_t *)value->data);
	else
		cursor->set_value(cursor, value);
	ret = cursor->insert(cursor);
	if (ret != 0 && ret != WT_NOTFOUND)
		die(ret, "col_update: %" PRIu64, keyno);

	if (!SINGLETHREADED)
		return;

	key_gen((uint8_t *)key->data, &key->size, keyno, 0);
	bdb_update(key->data, key->size, value->data, value->size, &notfound);
	(void)notfound_chk("col_update", ret, notfound, keyno);
}
Esempio n. 6
0
void
wts_verify(const char *tag)
{
	WT_CONNECTION *conn;
	WT_SESSION *session;
	int ret;

	conn = g.wts_conn;

	track("verify", 0ULL, NULL);

	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		die(ret, "connection.open_session");
	if (g.logging != 0)
		(void)session->msg_printf(session,
		    "=============== verify start ===============");
	if ((ret = session->verify(session, g.uri, NULL)) != 0)
		die(ret, "session.verify: %s: %s", g.uri, tag);
	if (g.logging != 0)
		(void)session->msg_printf(session,
		    "=============== verify stop ===============");
	if ((ret = session->close(session, NULL)) != 0)
		die(ret, "session.close");
}
Esempio n. 7
0
/*
 * nextprev --
 *	Read and verify the next/prev element in a row- or column-store file.
 */
static void
nextprev(WT_CURSOR *cursor, int next, int *notfoundp)
{
	WT_ITEM key, value, bdb_key, bdb_value;
	WT_SESSION *session;
	uint64_t keyno;
	int notfound, ret;
	uint8_t bitfield;
	const char *which;
	char *p;

	session = cursor->session;
	which = next ? "next" : "prev";

	keyno = 0;
	ret = next ? cursor->next(cursor) : cursor->prev(cursor);
	if (ret == 0)
		switch (g.c_file_type) {
		case FIX:
			if ((ret = cursor->get_key(cursor, &keyno)) == 0 &&
			    (ret = cursor->get_value(cursor, &bitfield)) == 0) {
				value.data = &bitfield;
				value.size = 1;
			}
			break;
		case ROW:
			if ((ret = cursor->get_key(cursor, &key)) == 0)
				ret = cursor->get_value(cursor, &value);
			break;
		case VAR:
			if ((ret = cursor->get_key(cursor, &keyno)) == 0)
				ret = cursor->get_value(cursor, &value);
			break;
		}
	if (ret != 0 && ret != WT_NOTFOUND)
		die(ret, "%s", which);
	*notfoundp = ret == WT_NOTFOUND;

	if (!SINGLETHREADED)
		return;

	/* Retrieve the BDB value. */
	bdb_np(next, &bdb_key.data, &bdb_key.size,
	    &bdb_value.data, &bdb_value.size, &notfound);
	if (notfound_chk(
	    next ? "nextprev(next)" : "nextprev(prev)", ret, notfound, keyno))
		return;

	/* Compare the two. */
	if (g.c_file_type == ROW) {
		if (key.size != bdb_key.size ||
		    memcmp(key.data, bdb_key.data, key.size) != 0) {
			fprintf(stderr, "nextprev: %s key mismatch:\n", which);
			print_item("bdb-key", &bdb_key);
			print_item(" wt-key", &key);
			die(0, NULL);
		}
	} else {
		if (keyno != (uint64_t)atoll(bdb_key.data)) {
			if ((p = strchr((char *)bdb_key.data, '.')) != NULL)
				*p = '\0';
			fprintf(stderr,
			    "nextprev: %s key mismatch: %.*s != %" PRIu64 "\n",
			    which,
			    (int)bdb_key.size, (char *)bdb_key.data, keyno);
			die(0, NULL);
		}
	}
	if (value.size != bdb_value.size ||
	    memcmp(value.data, bdb_value.data, value.size) != 0) {
		fprintf(stderr, "nextprev: %s value mismatch:\n", which);
		print_item("bdb-value", &bdb_value);
		print_item(" wt-value", &value);
		die(0, NULL);
	}

	if (g.logging == LOG_OPS)
		switch (g.c_file_type) {
		case FIX:
			(void)session->msg_printf(
			    session, "%-10s%" PRIu64 " {0x%02x}", which,
			    keyno, ((char *)value.data)[0]);
			break;
		case ROW:
			(void)session->msg_printf(session, "%-10s{%.*s/%.*s}",
			    which,
			    (int)key.size, (char *)key.data,
			    (int)value.size, (char *)value.data);
			break;
		case VAR:
			(void)session->msg_printf(
			    session, "%-10s%" PRIu64 " {%.*s}",
			    which, keyno, (int)value.size, (char *)value.data);
			break;
		}
}
Esempio n. 8
0
/*
 * read_row --
 *	Read and verify a single element in a row- or column-store file.
 */
static void
read_row(WT_CURSOR *cursor, WT_ITEM *key, uint64_t keyno)
{
	WT_ITEM bdb_value, value;
	WT_SESSION *session;
	int notfound, ret;
	uint8_t bitfield;

	session = cursor->session;

	/* Log the operation */
	if (g.logging == LOG_OPS)
		(void)session->msg_printf(
		    session, "%-10s%" PRIu64, "read", keyno);

	/* Retrieve the key/value pair by key. */
	switch (g.c_file_type) {
	case FIX:
	case VAR:
		cursor->set_key(cursor, keyno);
		break;
	case ROW:
		key_gen((uint8_t *)key->data, &key->size, keyno, 0);
		cursor->set_key(cursor, key);
		break;
	}

	if ((ret = cursor->search(cursor)) == 0) {
		if (g.c_file_type == FIX) {
			ret = cursor->get_value(cursor, &bitfield);
			value.data = &bitfield;
			value.size = 1;
		} else {
			memset(&value, 0, sizeof(value));
			ret = cursor->get_value(cursor, &value);
		}
	}
	if (ret != 0 && ret != WT_NOTFOUND)
		die(ret, "read_row: read row %" PRIu64, keyno);

	if (!SINGLETHREADED)
		return;

	/* Retrieve the BDB value. */
	memset(&bdb_value, 0, sizeof(bdb_value));
	bdb_read(keyno, &bdb_value.data, &bdb_value.size, &notfound);

	/*
	 * Check for not-found status.
	 *
	 * In fixed length stores, zero values at the end of the key space
	 * are treated as not found.  Treat this the same as a zero value
	 * in the key space, to match BDB's behavior.
	 */
	if (g.c_file_type == FIX && ret == WT_NOTFOUND) {
		bitfield = 0;
		ret = 0;
	}

	if (notfound_chk("read_row", ret, notfound, keyno))
		return;

	/* Compare the two. */
	if (value.size != bdb_value.size ||
	    memcmp(value.data, bdb_value.data, value.size) != 0) {
		fprintf(stderr,
		    "read_row: read row value mismatch %" PRIu64 ":\n", keyno);
		print_item("bdb", &bdb_value);
		print_item(" wt", &value);
		die(0, NULL);
	}
}
Esempio n. 9
0
/*
 * wts_ops --
 *	Perform a number of operations in a set of threads.
 */
void
wts_ops(void)
{
	TINFO *tinfo, total;
	WT_CONNECTION *conn;
	WT_SESSION *session;
	time_t now;
	int ret, running;
	uint32_t i;

	conn = g.wts_conn;

	/* Open a session. */
	session = NULL;
	if (g.logging == LOG_OPS) {
		if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
			die(ret, "connection.open_session");

		(void)time(&now);
		(void)session->msg_printf(session,
		    "===============\nthread ops start: %s===============",
		    ctime(&now));
	}

	if (SINGLETHREADED) {
		memset(&total, 0, sizeof(total));
		total.id = 1;
		(void)ops(&total);
	} else {
		/* Create thread structure. */
		if ((tinfo =
		    calloc((size_t)g.c_threads, sizeof(*tinfo))) == NULL)
			die(errno, "calloc");
		for (i = 0; i < g.c_threads; ++i) {
			tinfo[i].id = (int)i + 1;
			tinfo[i].state = TINFO_RUNNING;
			if ((ret = pthread_create(
			    &tinfo[i].tid, NULL, ops, &tinfo[i])) != 0)
				die(ret, "pthread_create");
		}

		/* Wait for the threads. */
		for (;;) {
			total.search =
			    total.insert = total.remove = total.update = 0;
			for (i = running = 0; i < g.c_threads; ++i) {
				total.search += tinfo[i].search;
				total.insert += tinfo[i].insert;
				total.remove += tinfo[i].remove;
				total.update += tinfo[i].update;
				switch (tinfo[i].state) {
				case TINFO_RUNNING:
					running = 1;
					break;
				case TINFO_COMPLETE:
					tinfo[i].state = TINFO_JOINED;
					(void)pthread_join(tinfo[i].tid, NULL);
					break;
				case TINFO_JOINED:
					break;
				}
			}
			track("read/write ops", 0ULL, &total);
			if (!running)
				break;
			(void)usleep(100000);		/* 1/10th of a second */
		}
		free(tinfo);
	}

	if (session != NULL) {
		(void)time(&now);
		(void)session->msg_printf(session,
		    "===============\nthread ops stop: %s===============",
		    ctime(&now));

		if ((ret = session->close(session, NULL)) != 0)
			die(ret, "session.close");
	}
}
Esempio n. 10
0
void
wts_load(void)
{
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_ITEM key, value;
	WT_SESSION *session;
	uint8_t *keybuf, *valbuf;
	int ret;

	conn = g.wts_conn;

	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		die(ret, "connection.open_session");

	if (g.logging != 0)
		(void)session->msg_printf(session,
		    "=============== bulk load start ===============");

	/*
	 * Avoid bulk load with a custom collator, because the order of
	 * insertion will not match the collation order.
	 */
	if ((ret = session->open_cursor(session, g.uri, NULL,
	    (g.type == ROW && g.c_reverse) ? NULL : "bulk", &cursor)) != 0)
		die(ret, "session.open_cursor");

	/* Set up the default key buffer. */
	memset(&key, 0, sizeof(key));
	key_gen_setup(&keybuf);
	memset(&value, 0, sizeof(value));
	val_gen_setup(&valbuf);

	for (;;) {
		if (++g.key_cnt > g.c_rows) {
			g.key_cnt = g.rows = g.c_rows;
			break;
		}

		/* Report on progress every 100 inserts. */
		if (g.key_cnt % 100 == 0)
			track("bulk load", g.key_cnt, NULL);

		key_gen(keybuf, &key.size, (uint64_t)g.key_cnt, 0);
		key.data = keybuf;
		value_gen(valbuf, &value.size, (uint64_t)g.key_cnt);
		value.data = valbuf;

		switch (g.type) {
		case FIX:
			if (g.logging == LOG_OPS)
				(void)session->msg_printf(session,
				    "%-10s %" PRIu32 " {0x%02" PRIx8 "}",
				    "bulk V",
				    g.key_cnt, ((uint8_t *)value.data)[0]);
			cursor->set_value(cursor, *(uint8_t *)value.data);
			break;
		case VAR:
			cursor->set_value(cursor, &value);
			if (g.logging == LOG_OPS)
				(void)session->msg_printf(session,
				    "%-10s %" PRIu32 " {%.*s}", "bulk V",
				    g.key_cnt,
				    (int)value.size, (char *)value.data);
			break;
		case ROW:
			cursor->set_key(cursor, &key);
			if (g.logging == LOG_OPS)
				(void)session->msg_printf(session,
				    "%-10s %" PRIu32 " {%.*s}", "bulk K",
				    g.key_cnt, (int)key.size, (char *)key.data);
			cursor->set_value(cursor, &value);
			if (g.logging == LOG_OPS)
				(void)session->msg_printf(session,
				    "%-10s %" PRIu32 " {%.*s}", "bulk V",
				    g.key_cnt,
				    (int)value.size, (char *)value.data);
			break;
		}

		if ((ret = cursor->insert(cursor)) != 0)
			die(ret, "cursor.insert");

		if (!SINGLETHREADED)
			continue;

		/* Insert the item into BDB. */
		bdb_insert(key.data, key.size, value.data, value.size);
	}

	if ((ret = cursor->close(cursor)) != 0)
		die(ret, "cursor.close");

	if (g.logging != 0)
		(void)session->msg_printf(session,
		    "=============== bulk load stop ===============");

	if ((ret = session->close(session, NULL)) != 0)
		die(ret, "session.close");

	free(keybuf);
	free(valbuf);
}