コード例 #1
0
ファイル: main.c プロジェクト: judahschvimer/mongo
void populate(TEST_OPTS *opts)
{
	WT_CURSOR *maincur;
	WT_SESSION *session;
	uint32_t key;
	int balance, i, flag, post;
	WT_RAND_STATE rnd;

	testutil_check(__wt_random_init_seed(NULL, &rnd));

	testutil_check(opts->conn->open_session(
	    opts->conn, NULL, NULL, &session));

	testutil_check(session->open_cursor(session, opts->uri, NULL, NULL,
	    &maincur));

	for (i = 0; i < N_INSERT; i++) {
		testutil_check(session->begin_transaction(session, NULL));
		key = (__wt_random(&rnd) % (N_RECORDS));
		maincur->set_key(maincur, key);
		if (__wt_random(&rnd) % 11 == 0)
			post = 54321;
		else
			post = i % 100000;
		if (__wt_random(&rnd) % 4 == 0) {
			balance = -100;
			flag = 1;
		} else {
			balance = 100 * (i + 1);
			flag = 0;
		}
		maincur->set_value(maincur, post, balance, flag, key);
		testutil_check(maincur->insert(maincur));
		testutil_check(session->commit_transaction(session, NULL));
	}
	maincur->close(maincur);
	session->close(session, NULL);
}
コード例 #2
0
ファイル: ex_stat.c プロジェクト: DINKIN/mongo
int
main(int argc, char *argv[])
{
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_SESSION *session;

	home = example_setup(argc, argv);

	error_check(
	    wiredtiger_open(home, NULL, "create,statistics=(all)", &conn));
	error_check(conn->open_session(conn, NULL, NULL, &session));
	error_check(session->create(session,
	    "table:access", "key_format=S,value_format=S,columns=(k,v)"));

	error_check(session->open_cursor(
	    session, "table:access", NULL, NULL, &cursor));
	cursor->set_key(cursor, "key");
	cursor->set_value(cursor, "value");
	error_check(cursor->insert(cursor));
	error_check(cursor->close(cursor));

	error_check(session->checkpoint(session, NULL));

	print_database_stats(session);

	print_file_stats(session);

	print_join_cursor_stats(session);

	print_overflow_pages(session);

	print_derived_stats(session);

	error_check(conn->close(conn, NULL));

	return (EXIT_SUCCESS);
}
コード例 #3
0
TEST_F(WiredTigerRecoveryUnitTestFixture,
       LocalReadOnADocumentBeingPreparedDoesntTriggerPrepareConflict) {
    // Prepare but don't commit a transaction
    ru1->beginUnitOfWork(clientAndCtx1.second.get());
    WT_CURSOR* cursor;
    getCursor(ru1, &cursor);
    cursor->set_key(cursor, "key");
    cursor->set_value(cursor, "value");
    invariantWTOK(cursor->insert(cursor));
    ru1->setPrepareTimestamp({1, 1});
    ru1->prepareUnitOfWork();

    // A transaction that chooses to ignore prepare conflicts does not see the record instead of
    // returning a prepare conflict.
    ru2->beginUnitOfWork(clientAndCtx2.second.get());
    ru2->setIgnorePrepared(true);
    getCursor(ru2, &cursor);
    cursor->set_key(cursor, "key");
    int ret = cursor->search(cursor);
    ASSERT_EQ(WT_NOTFOUND, ret);

    ru1->abortUnitOfWork();
    ru2->abortUnitOfWork();
}
コード例 #4
0
/*
 * json_data --
 *	Parse the data portion of the JSON input, and insert all
 *	values.
 */
static int
json_data(WT_SESSION *session, JSON_INPUT_STATE *ins, CONFIG_LIST *clp,
    uint32_t flags)
{
	WT_CURSOR *cursor;
	WT_DECL_RET;
	char config[64], *endp, *uri;
	const char *keyformat;
	int isrec, nfield, nkeys, toktype, tret;
	size_t keystrlen;
	ssize_t gotnolen;
	uint64_t gotno, recno;

	cursor = NULL;
	uri = NULL;

	/* Reorder and check the list. */
	if ((ret = config_reorder(clp->list)) != 0)
		goto err;

	/* Update config based on command-line configuration. */
	if ((ret = config_update(session, clp->list)) != 0)
		goto err;

	/* Create the items collected. */
	if ((ret = config_exec(session, clp->list)) != 0)
		goto err;

	uri = clp->list[0];
	(void)snprintf(config, sizeof(config),
	    "dump=json%s%s",
	    LF_ISSET(LOAD_JSON_APPEND) ? ",append" : "",
	    LF_ISSET(LOAD_JSON_NO_OVERWRITE) ? ",overwrite=false" : "");
	if ((ret = session->open_cursor(
	    session, uri, NULL, config, &cursor)) != 0) {
		ret = util_err(ret, "%s: session.open", uri);
		goto err;
	}
	keyformat = cursor->key_format;
	isrec = (strcmp(keyformat, "r") == 0);
	for (nkeys = 0; *keyformat; keyformat++)
		if (!isdigit(*keyformat))
			nkeys++;

	recno = 0;
	while (json_peek(session, ins) == '{') {
		nfield = 0;
		JSON_EXPECT(session, ins, '{');
		if (ins->kvraw == NULL) {
			if ((ins->kvraw = (char *)malloc(1)) == NULL) {
				ret = util_err(errno, NULL);
				goto err;
			}
		}
		ins->kvraw[0] = '\0';
		ins->kvrawstart = JSON_INPUT_POS(ins);
		keystrlen = 0;
		while (json_peek(session, ins) == 's') {
			JSON_EXPECT(session, ins, 's');
			JSON_EXPECT(session, ins, ':');
			toktype = json_peek(session, ins);
			JSON_EXPECT(session, ins, toktype);
			if (isrec && nfield == 0) {
				/* Verify the dump has recnos in order. */
				recno++;
				gotno = __wt_strtouq(ins->tokstart, &endp, 0);
				gotnolen = (endp - ins->tokstart);
				if (recno != gotno ||
				    ins->toklen != (size_t)gotnolen) {
					ret = util_err(0,
					    "%s: recno out of order", uri);
					goto err;
				}
			}
			if (++nfield == nkeys) {
				size_t curpos = JSON_INPUT_POS(ins);
				if ((ret = json_kvraw_append(ins,
				    (char *)ins->line.mem + ins->kvrawstart,
				    curpos - ins->kvrawstart)) != 0)
					goto err;
				ins->kvrawstart = curpos;
				keystrlen = strlen(ins->kvraw);
			}
			if (json_peek(session, ins) != ',')
				break;
			JSON_EXPECT(session, ins, ',');
			if (json_peek(session, ins) != 's')
				goto err;
		}
		if (json_kvraw_append(ins, ins->line.mem, JSON_INPUT_POS(ins)))
			goto err;

		ins->kvraw[keystrlen] = '\0';
		if (!LF_ISSET(LOAD_JSON_APPEND))
			cursor->set_key(cursor, ins->kvraw);
		/* skip over inserted space and comma */
		cursor->set_value(cursor, &ins->kvraw[keystrlen+2]);
		if ((ret = cursor->insert(cursor)) != 0) {
			ret = util_err(ret, "%s: cursor.insert", uri);
			goto err;
		}

		JSON_EXPECT(session, ins, '}');
		if (json_peek(session, ins) != ',')
			break;
		JSON_EXPECT(session, ins, ',');
		if (json_peek(session, ins) != '{')
			goto err;
	}
	if (0) {
err:		if (ret == 0)
			ret = EINVAL;
	}
	/*
	 * Technically, we don't have to close the cursor because the session
	 * handle will do it for us, but I'd like to see the flush to disk and
	 * the close succeed, it's better to fail early when loading files.
	 */
	if (cursor != NULL && (tret = cursor->close(cursor)) != 0) {
		tret = util_err(tret, "%s: cursor.close", uri);
		if (ret == 0)
			ret = tret;
	}
	if (ret == 0)
		ret = util_flush(session, uri);
	return (ret);
}
コード例 #5
0
ファイル: ex_all.c プロジェクト: ezhangle/node-wiredtiger
int
transaction_ops(WT_CONNECTION *conn, WT_SESSION *session)
{
	WT_CURSOR *cursor;
	int ret;

	/*! [transaction commit/rollback] */
	ret =
	    session->open_cursor(session, "table:mytable", NULL, NULL, &cursor);
	ret = session->begin_transaction(session, NULL);
	/*
	 * Cursors may be opened before or after the transaction begins, and in
	 * either case, subsequent operations are included in the transaction.
	 * The begin_transaction call resets all open cursors.
	 */

	cursor->set_key(cursor, "key");
	cursor->set_value(cursor, "value");
	switch (ret = cursor->update(cursor)) {
	case 0:					/* Update success */
		ret = session->commit_transaction(session, NULL);
		/*
		 * The commit_transaction call resets all open cursors.
		 * If commit_transaction fails, the transaction was rolled-back.
		 */
		break;
	case WT_DEADLOCK:			/* Update conflict */
	default:				/* Other error */
		ret = session->rollback_transaction(session, NULL);
		/* The rollback_transaction call resets all open cursors. */
		break;
	}

	/* Cursors remain open and may be used for multiple transactions. */
	/*! [transaction commit/rollback] */
	ret = cursor->close(cursor);

	/*! [transaction isolation] */
	/* A single transaction configured for snapshot isolation. */
	ret =
	    session->open_cursor(session, "table:mytable", NULL, NULL, &cursor);
	ret = session->begin_transaction(session, "isolation=snapshot");
	cursor->set_key(cursor, "some-key");
	cursor->set_value(cursor, "some-value");
	ret = cursor->update(cursor);
	ret = session->commit_transaction(session, NULL);
	/*! [transaction isolation] */

	/*! [session isolation configuration] */
	/* Open a session configured for read-uncommitted isolation. */
	ret = conn->open_session(
	    conn, NULL, "isolation=read_uncommitted", &session);
	/*! [session isolation configuration] */

	/*! [session isolation re-configuration] */
	/* Re-configure a session for snapshot isolation. */
	ret = session->reconfigure(session, "isolation=snapshot");
	/*! [session isolation re-configuration] */

	return (ret);
}
コード例 #6
0
ファイル: ex_all.c プロジェクト: ezhangle/node-wiredtiger
int
session_ops(WT_SESSION *session)
{
	int ret;

	/*! [Reconfigure a session] */
	ret = session->reconfigure(session, "isolation=snapshot");
	/*! [Reconfigure a session] */

	/*! [Create a table] */
	ret = session->create(session,
	    "table:mytable", "key_format=S,value_format=S");
	/*! [Create a table] */
	ret = session->drop(session, "table:mytable", NULL);

	/*! [Create a column-store table] */
	ret = session->create(session,
	    "table:mytable", "key_format=r,value_format=S");
	/*! [Create a column-store table] */
	ret = session->drop(session, "table:mytable", NULL);

	/*! [Create a table with columns] */
	/*
	 * Create a table with columns: keys are record numbers, values are
	 * (string, signed 32-bit integer, unsigned 16-bit integer).
	 */
	ret = session->create(session, "table:mytable",
	    "key_format=r,value_format=SiH,"
	    "columns=(id,department,salary,year-started)");
	/*! [Create a table with columns] */
	ret = session->drop(session, "table:mytable", NULL);

	/*
	 * This example code gets run, and the compression libraries might not
	 * be loaded, causing the create to fail.  The documentation requires
	 * the code snippets, use #ifdef's to avoid running it.
	 */
#ifdef MIGHT_NOT_RUN
	/*! [Create a bzip2 compressed table] */
	ret = session->create(session,
	    "table:mytable",
	    "block_compressor=bzip2,key_format=S,value_format=S");
	/*! [Create a bzip2 compressed table] */
	ret = session->drop(session, "table:mytable", NULL);

	/*! [Create a snappy compressed table] */
	ret = session->create(session,
	    "table:mytable",
	    "block_compressor=snappy,key_format=S,value_format=S");
	/*! [Create a snappy compressed table] */
	ret = session->drop(session, "table:mytable", NULL);

	/*! [Create a zlib compressed table] */
	ret = session->create(session,
	    "table:mytable",
	    "block_compressor=zlib,key_format=S,value_format=S");
	/*! [Create a zlib compressed table] */
	ret = session->drop(session, "table:mytable", NULL);
#endif

	/*! [Configure checksums to uncompressed] */
	ret = session->create(session, "table:mytable",
	    "key_format=S,value_format=S,checksum=uncompressed");
	/*! [Configure checksums to uncompressed] */
	ret = session->drop(session, "table:mytable", NULL);

	/*! [Configure dictionary compression on] */
	ret = session->create(session, "table:mytable",
	    "key_format=S,value_format=S,dictionary=1000");
	/*! [Configure dictionary compression on] */
	ret = session->drop(session, "table:mytable", NULL);

	/*! [Configure key prefix compression off] */
	ret = session->create(session, "table:mytable",
	    "key_format=S,value_format=S,prefix_compression=false");
	/*! [Configure key prefix compression off] */
	ret = session->drop(session, "table:mytable", NULL);

#ifdef MIGHT_NOT_RUN
						/* Requires sync_file_range */
	/*! [os_cache_dirty_max configuration] */
	ret = session->create(
	    session, "table:mytable", "os_cache_dirty_max=500MB");
	/*! [os_cache_dirty_max configuration] */
	ret = session->drop(session, "table:mytable", NULL);

						/* Requires posix_fadvise */
	/*! [os_cache_max configuration] */
	ret = session->create(session, "table:mytable", "os_cache_max=1GB");
	/*! [os_cache_max configuration] */
	ret = session->drop(session, "table:mytable", NULL);
#endif
	/*! [Configure block_allocation] */
	ret = session->create(session, "table:mytable",
	    "key_format=S,value_format=S,block_allocation=first");
	/*! [Configure block_allocation] */
	ret = session->drop(session, "table:mytable", NULL);

	/*! [Create a cache-resident object] */
	ret = session->create(session,
	    "table:mytable", "key_format=r,value_format=S,cache_resident=true");
	/*! [Create a cache-resident object] */
	ret = session->drop(session, "table:mytable", NULL);

	{
	/* Create a table for the session operations. */
	ret = session->create(
	    session, "table:mytable", "key_format=S,value_format=S");

	/*! [Compact a table] */
	ret = session->compact(session, "table:mytable", NULL);
	/*! [Compact a table] */

	/*! [Rename a table] */
	ret = session->rename(session, "table:old", "table:new", NULL);
	/*! [Rename a table] */

	/*! [Salvage a table] */
	ret = session->salvage(session, "table:mytable", NULL);
	/*! [Salvage a table] */

	/*! [Truncate a table] */
	ret = session->truncate(session, "table:mytable", NULL, NULL, NULL);
	/*! [Truncate a table] */

	{
	/*
	 * Insert a pair of keys so we can truncate a range.
	 */
	WT_CURSOR *cursor;
	ret = session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor);
	cursor->set_key(cursor, "June01");
	cursor->set_value(cursor, "value");
	ret = cursor->update(cursor);
	cursor->set_key(cursor, "June30");
	cursor->set_value(cursor, "value");
	ret = cursor->update(cursor);
	cursor->close(cursor);

	{
	/*! [Truncate a range] */
	WT_CURSOR *start, *stop;

	ret = session->open_cursor(
	    session, "table:mytable", NULL, NULL, &start);
	start->set_key(start, "June01");
	ret = start->search(start);

	ret = session->open_cursor(
	    session, "table:mytable", NULL, NULL, &stop);
	stop->set_key(stop, "June30");
	ret = stop->search(stop);

	ret = session->truncate(session, NULL, start, stop, NULL);
	/*! [Truncate a range] */
	}
	}

	/*! [Upgrade a table] */
	ret = session->upgrade(session, "table:mytable", NULL);
	/*! [Upgrade a table] */

	/*! [Verify a table] */
	ret = session->verify(session, "table:mytable", NULL);
	/*! [Verify a table] */

	/*! [Drop a table] */
	ret = session->drop(session, "table:mytable", NULL);
	/*! [Drop a table] */
	}

	/*! [Close a session] */
	ret = session->close(session, NULL);
	/*! [Close a session] */

	return (ret);
}
コード例 #7
0
ファイル: ex_all.c プロジェクト: ksuarz/mongo
int
transaction_ops(WT_CONNECTION *conn, WT_SESSION *session)
{
	WT_CURSOR *cursor;
	int ret;

	/*! [transaction commit/rollback] */
	/*
	 * Cursors may be opened before or after the transaction begins, and in
	 * either case, subsequent operations are included in the transaction.
	 * Opening cursors before the transaction begins allows applications to
	 * cache cursors and use them for multiple operations.
	 */
	ret =
	    session->open_cursor(session, "table:mytable", NULL, NULL, &cursor);
	ret = session->begin_transaction(session, NULL);

	cursor->set_key(cursor, "key");
	cursor->set_value(cursor, "value");
	switch (ret = cursor->update(cursor)) {
	case 0:					/* Update success */
		ret = session->commit_transaction(session, NULL);
		/*
		 * If commit_transaction succeeds, cursors remain positioned; if
		 * commit_transaction fails, the transaction was rolled-back and
		 * and all cursors are reset.
		 */
		break;
	case WT_ROLLBACK:			/* Update conflict */
	default:				/* Other error */
		ret = session->rollback_transaction(session, NULL);
		/* The rollback_transaction call resets all cursors. */
		break;
	}

	/*
	 * Cursors remain open and may be used for multiple transactions.
	 */
	/*! [transaction commit/rollback] */
	ret = cursor->close(cursor);

	/*! [transaction isolation] */
	/* A single transaction configured for snapshot isolation. */
	ret =
	    session->open_cursor(session, "table:mytable", NULL, NULL, &cursor);
	ret = session->begin_transaction(session, "isolation=snapshot");
	cursor->set_key(cursor, "some-key");
	cursor->set_value(cursor, "some-value");
	ret = cursor->update(cursor);
	ret = session->commit_transaction(session, NULL);
	/*! [transaction isolation] */

	/*! [session isolation configuration] */
	/* Open a session configured for read-uncommitted isolation. */
	ret = conn->open_session(
	    conn, NULL, "isolation=read_uncommitted", &session);
	/*! [session isolation configuration] */

	/*! [session isolation re-configuration] */
	/* Re-configure a session for snapshot isolation. */
	ret = session->reconfigure(session, "isolation=snapshot");
	/*! [session isolation re-configuration] */

	{
	/*! [transaction pinned range] */
	/* Check the transaction ID range pinned by the session handle. */
	uint64_t range;

	ret = session->transaction_pinned_range(session, &range);
	/*! [transaction pinned range] */
	}

	return (ret);
}
コード例 #8
0
ファイル: recovery.c プロジェクト: Zhangwusheng/wiredtiger
/*
 * Child process creates the database and table, and then writes data into
 * the table until it is killed by the parent.
 */
static void
fill_db(void)
{
	FILE *fp;
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_ITEM data;
	WT_RAND_STATE rnd;
	WT_SESSION *session;
	uint64_t i;
	int ret;
	uint8_t buf[MAX_VAL];

	__wt_random_init(&rnd);
	memset(buf, 0, sizeof(buf));
	/*
	 * Initialize the first 25% to random values.  Leave a bunch of data
	 * space at the end to emphasize zero data.
	 */
	for (i = 0; i < MAX_VAL/4; i++)
		buf[i] = (uint8_t)__wt_random(&rnd);

	/*
	 * Run in the home directory so that the records file is in there too.
	 */
	chdir(home);
	if ((ret = wiredtiger_open(NULL, NULL, ENV_CONFIG, &conn)) != 0)
		testutil_die(ret, "wiredtiger_open");
	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		testutil_die(ret, "WT_CONNECTION:open_session");
	if ((ret = session->create(session,
	    uri, "key_format=Q,value_format=u")) != 0)
		testutil_die(ret, "WT_SESSION.create: %s", uri);
	if ((ret =
	    session->open_cursor(session, uri, NULL, NULL, &cursor)) != 0)
		testutil_die(ret, "WT_SESSION.open_cursor: %s", uri);

	/*
	 * Keep a separate file with the records we wrote for checking.
	 */
	(void)unlink(RECORDS_FILE);
	if ((fp = fopen(RECORDS_FILE, "w")) == NULL)
		testutil_die(errno, "fopen");
	/*
	 * Set to no buffering.
	 */
	setvbuf(fp, NULL, _IONBF, 0);

	/*
	 * Write data into the table until we are killed by the parent.
	 * The data in the buffer is already set to random content.
	 */
	data.data = buf;
	for (i = 0;; ++i) {
		data.size = __wt_random(&rnd) % MAX_VAL;
		cursor->set_key(cursor, i);
		cursor->set_value(cursor, &data);
		if ((ret = cursor->insert(cursor)) != 0)
			testutil_die(ret, "WT_CURSOR.insert");
		/*
		 * Save the key separately for checking later.
		 */
		if (fprintf(fp, "%" PRIu64 "\n", i) == -1)
			testutil_die(errno, "fprintf");
		if (i % 5000)
			__wt_yield();
	}
}
コード例 #9
0
ファイル: readonly.c プロジェクト: jbreams/mongo
int
main(int argc, char *argv[])
{
	WT_CONNECTION *conn, *conn2, *conn3, *conn4;
	WT_CURSOR *cursor;
	WT_ITEM data;
	WT_SESSION *session;
	uint64_t i;
	int ch, status, op, ret;
	bool child;
	const char *working_dir;
	char cmd[512];
	uint8_t buf[MAX_VAL];

	if ((progname = strrchr(argv[0], DIR_DELIM)) == NULL)
		progname = argv[0];
	else
		++progname;
	/*
	 * Needed unaltered for system command later.
	 */
	saved_argv0 = argv[0];

	working_dir = "WT_RD";
	child = false;
	op = OP_READ;
	while ((ch = __wt_getopt(progname, argc, argv, "Rh:W")) != EOF)
		switch (ch) {
		case 'R':
			child = true;
			op = OP_READ;
			break;
		case 'W':
			child = true;
			op = OP_WRITE;
			break;
		case 'h':
			working_dir = __wt_optarg;
			break;
		default:
			usage();
		}
	argc -= __wt_optind;
	argv += __wt_optind;
	if (argc != 0)
		usage();

	/*
	 * Set up all the directory names.
	 */
	testutil_work_dir_from_path(home, sizeof(home), working_dir);
	(void)snprintf(home_wr, sizeof(home_wr), "%s%s", home, HOME_WR_SUFFIX);
	(void)snprintf(home_rd, sizeof(home_rd), "%s%s", home, HOME_RD_SUFFIX);
	(void)snprintf(
	    home_rd2, sizeof(home_rd2), "%s%s", home, HOME_RD2_SUFFIX);
	if (!child) {
		testutil_make_work_dir(home);
		testutil_make_work_dir(home_wr);
		testutil_make_work_dir(home_rd);
		testutil_make_work_dir(home_rd2);
	} else
		/*
		 * We are a child process, we just want to call
		 * the open_dbs with the directories we have.
		 * The child function will exit.
		 */
		open_dbs(op, home, home_wr, home_rd, home_rd2);

	/*
	 * Parent creates a database and table.  Then cleanly shuts down.
	 * Then copy database to read-only directory and chmod.
	 * Also copy database to read-only directory and remove the lock
	 * file.  One read-only database will have a lock file in the
	 * file system and the other will not.
	 * Parent opens all databases with read-only configuration flag.
	 * Parent forks off child who tries to also open all databases
	 * with the read-only flag.  It should error on the writeable
	 * directory, but allow it on the read-only directories.
	 * The child then confirms it can read all the data.
	 */
	/*
	 * Run in the home directory and create the table.
	 */
	if ((ret = wiredtiger_open(home, NULL, ENV_CONFIG, &conn)) != 0)
		testutil_die(ret, "wiredtiger_open");
	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		testutil_die(ret, "WT_CONNECTION:open_session");
	if ((ret = session->create(session,
	    uri, "key_format=Q,value_format=u")) != 0)
		testutil_die(ret, "WT_SESSION.create: %s", uri);
	if ((ret =
	    session->open_cursor(session, uri, NULL, NULL, &cursor)) != 0)
		testutil_die(ret, "WT_SESSION.open_cursor: %s", uri);

	/*
	 * Write data into the table and then cleanly shut down connection.
	 */
	memset(buf, 0, sizeof(buf));
	data.data = buf;
	data.size = MAX_VAL;
	for (i = 0; i < MAX_KV; ++i) {
		cursor->set_key(cursor, i);
		cursor->set_value(cursor, &data);
		if ((ret = cursor->insert(cursor)) != 0)
			testutil_die(ret, "WT_CURSOR.insert");
	}
	if ((ret = conn->close(conn, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");

	/*
	 * Copy the database.  Remove any lock file from one copy
	 * and chmod the copies to be read-only permissions.
	 */
	(void)snprintf(cmd, sizeof(cmd),
	    "cp -rp %s/* %s; rm -f %s/WiredTiger.lock",
	    home, home_wr, home_wr);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);

	(void)snprintf(cmd, sizeof(cmd),
	    "cp -rp %s/* %s; chmod 0555 %s; chmod -R 0444 %s/*",
	    home, home_rd, home_rd, home_rd);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);

	(void)snprintf(cmd, sizeof(cmd),
	    "cp -rp %s/* %s; rm -f %s/WiredTiger.lock; "
	    "chmod 0555 %s; chmod -R 0444 %s/*",
	    home, home_rd2, home_rd2, home_rd2, home_rd2);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);

	/*
	 * Run four scenarios.  Sometimes expect errors, sometimes success.
	 * The writable database directories should always fail to allow the
	 * child to open due to the lock file.  The read-only ones will only
	 * succeed when the child attempts read-only.
	 *
	 * 1.  Parent has read-only handle to all databases.  Child opens
	 *     read-only also.
	 * 2.  Parent has read-only handle to all databases.  Child opens
	 *     read-write.
	 * 3.  Parent has read-write handle to writable databases and
	 *     read-only to read-only databases.  Child opens read-only.
	 * 4.  Parent has read-write handle to writable databases and
	 *     read-only to read-only databases.  Child opens read-write.
	 */
	/*
	 * Open a connection handle to all databases.
	 */
	fprintf(stderr, " *** Expect several error messages from WT ***\n");
	/*
	 * Scenario 1.
	 */
	if ((ret = wiredtiger_open(home, NULL, ENV_CONFIG_RD, &conn)) != 0)
		testutil_die(ret, "wiredtiger_open original home");
	if ((ret = wiredtiger_open(home_wr, NULL, ENV_CONFIG_RD, &conn2)) != 0)
		testutil_die(ret, "wiredtiger_open write nolock");
	if ((ret = wiredtiger_open(home_rd, NULL, ENV_CONFIG_RD, &conn3)) != 0)
		testutil_die(ret, "wiredtiger_open readonly");
	if ((ret = wiredtiger_open(home_rd2, NULL, ENV_CONFIG_RD, &conn4)) != 0)
		testutil_die(ret, "wiredtiger_open readonly nolock");

	/*
	 * Create a child to also open a connection handle to the databases.
	 * We cannot use fork here because using fork the child inherits the
	 * same memory image.  Therefore the WT process structure is set in
	 * the child even though it should not be.  So use 'system' to spawn
	 * an entirely new process.
	 *
	 * The child will exit with success if its test passes.
	 */
	(void)snprintf(
	    cmd, sizeof(cmd), "%s -h %s -R", saved_argv0, working_dir);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);
	if (WEXITSTATUS(status) != 0)
		testutil_die(WEXITSTATUS(status), "system: %s", cmd);

	/*
	 * Scenario 2.  Run child with writable config.
	 */
	(void)snprintf(
	    cmd, sizeof(cmd), "%s -h %s -W", saved_argv0, working_dir);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);
	if (WEXITSTATUS(status) != 0)
		testutil_die(WEXITSTATUS(status), "system: %s", cmd);

	/*
	 * Reopen the two writable directories and rerun the child.
	 */
	if ((ret = conn->close(conn, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if ((ret = conn2->close(conn2, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if ((ret = wiredtiger_open(home, NULL, ENV_CONFIG_RD, &conn)) != 0)
		testutil_die(ret, "wiredtiger_open original home");
	if ((ret = wiredtiger_open(home_wr, NULL, ENV_CONFIG_RD, &conn2)) != 0)
		testutil_die(ret, "wiredtiger_open write nolock");
	/*
	 * Scenario 3.  Child read-only.
	 */
	(void)snprintf(
	    cmd, sizeof(cmd), "%s -h %s -R", saved_argv0, working_dir);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);
	if (WEXITSTATUS(status) != 0)
		testutil_die(WEXITSTATUS(status), "system: %s", cmd);

	/*
	 * Scenario 4.  Run child with writable config.
	 */
	(void)snprintf(
	    cmd, sizeof(cmd), "%s -h %s -W", saved_argv0, working_dir);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);
	if (WEXITSTATUS(status) != 0)
		testutil_die(WEXITSTATUS(status), "system: %s", cmd);

	/*
	 * Clean-up.
	 */
	if ((ret = conn->close(conn, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if ((ret = conn2->close(conn2, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if ((ret = conn3->close(conn3, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if ((ret = conn4->close(conn4, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	/*
	 * We need to chmod the read-only databases back so that they can
	 * be removed by scripts.
	 */
	(void)snprintf(cmd, sizeof(cmd), "chmod 0777 %s %s", home_rd, home_rd2);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);
	(void)snprintf(cmd, sizeof(cmd), "chmod -R 0666 %s/* %s/*",
	    home_rd, home_rd2);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);
	printf(" *** Readonly test successful ***\n");
	return (EXIT_SUCCESS);
}
コード例 #10
0
ファイル: ex_log.c プロジェクト: XinzeChi/wiredtiger
int
main(void)
{
	WT_CONNECTION *wt_conn;
	WT_CURSOR *cursor;
	WT_SESSION *session;
	int i, record_count, ret;
	char cmd_buf[256], k[16], v[16];

	snprintf(cmd_buf, sizeof(cmd_buf), "rm -rf %s %s && mkdir %s %s",
	    home1, home2, home1, home2);
	if ((ret = system(cmd_buf)) != 0) {
		fprintf(stderr, "%s: failed ret %d\n", cmd_buf, ret);
		return (ret);
	}
	if ((ret = wiredtiger_open(home1, NULL, CONN_CONFIG, &wt_conn)) != 0) {
		fprintf(stderr, "Error connecting to %s: %s\n",
		    home1, wiredtiger_strerror(ret));
		return (ret);
	}

	ret = wt_conn->open_session(wt_conn, NULL, NULL, &session);
	ret = session->create(session, uri, "key_format=S,value_format=S");

	ret = session->open_cursor(session, uri, NULL, NULL, &cursor);
	/*
	 * Perform some operations with individual auto-commit transactions.
	 */
	for (record_count = 0, i = 0; i < MAX_KEYS; i++, record_count++) {
		snprintf(k, sizeof(k), "key%d", i);
		snprintf(v, sizeof(v), "value%d", i);
		cursor->set_key(cursor, k);
		cursor->set_value(cursor, v);
		ret = cursor->insert(cursor);
	}
	ret = session->begin_transaction(session, NULL);
	/*
	 * Perform some operations within a single transaction.
	 */
	for (i = MAX_KEYS; i < MAX_KEYS+5; i++, record_count++) {
		snprintf(k, sizeof(k), "key%d", i);
		snprintf(v, sizeof(v), "value%d", i);
		cursor->set_key(cursor, k);
		cursor->set_value(cursor, v);
		ret = cursor->insert(cursor);
	}
	ret = session->commit_transaction(session, NULL);
	ret = cursor->close(cursor);

	/*! [log cursor printf] */
	ret = session->log_printf(session, "Wrote %d records", record_count);
	/*! [log cursor printf] */

	/*
	 * Close and reopen the connection so that the log ends up with
	 * a variety of records such as file sync and checkpoint.  We
	 * have archiving turned off.
	 */
	ret = wt_conn->close(wt_conn, NULL);
	if ((ret = wiredtiger_open(home1, NULL, CONN_CONFIG, &wt_conn)) != 0) {
		fprintf(stderr, "Error connecting to %s: %s\n",
		    home1, wiredtiger_strerror(ret));
		return (ret);
	}

	ret = wt_conn->open_session(wt_conn, NULL, NULL, &session);
	ret = simple_walk_log(session);
	ret = walk_log(session);
	ret = wt_conn->close(wt_conn, NULL);
	return (ret);
}
コード例 #11
0
ファイル: huge.c プロジェクト: Arikes/mongo
static void
run(CONFIG *cp, int bigkey, size_t bytes)
{
	WT_CONNECTION *conn;
	WT_SESSION *session;
	WT_CURSOR *cursor;
	uint64_t keyno;
	int ret;
	void *p;

	big[bytes - 1] = '\0';

	printf(SIZET_FMT "%s%s: %s %s big %s\n",
	    bytes < MEGABYTE ? bytes :
	    (bytes < GIGABYTE ? bytes / MEGABYTE : bytes / GIGABYTE),
	    bytes < MEGABYTE ? "" :
	    (bytes < GIGABYTE ?
	    (bytes % MEGABYTE == 0 ? "" : "+") :
	    (bytes % GIGABYTE == 0 ? "" : "+")),
	    bytes < MEGABYTE ? "B" : (bytes < GIGABYTE ? "MB" : "GB"),
	    cp->uri, cp->config, bigkey ? "key" : "value");

	testutil_make_work_dir(home);

	/*
	 * Open/create the database, connection, session and cursor; set the
	 * cache size large, we don't want to try and evict anything.
	 */
	if ((ret = wiredtiger_open(
	    home, NULL, "create,cache_size=10GB", &conn)) != 0)
		testutil_die(ret, "wiredtiger_open");
	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		testutil_die(ret, "WT_CONNECTION.open_session");
	if ((ret = session->create(session, cp->uri, cp->config)) != 0)
		testutil_die(ret,
		    "WT_SESSION.create: %s %s", cp->uri, cp->config);
	if ((ret =
	    session->open_cursor(session, cp->uri, NULL, NULL, &cursor)) != 0)
		testutil_die(ret, "WT_SESSION.open_cursor: %s", cp->uri);

	/* Set the key/value. */
	if (bigkey)
		cursor->set_key(cursor, big);
	else if (cp->recno) {
		keyno = 1;
		cursor->set_key(cursor, keyno);
	} else
		cursor->set_key(cursor, "key001");
	cursor->set_value(cursor, big);

	/* Insert the record (use update, insert discards the key). */
	if ((ret = cursor->update(cursor)) != 0)
		testutil_die(ret, "WT_CURSOR.insert");

	/* Retrieve the record and check it. */
	if ((ret = cursor->search(cursor)) != 0)
		testutil_die(ret, "WT_CURSOR.search");
	if (bigkey && (ret = cursor->get_key(cursor, &p)) != 0)
		testutil_die(ret, "WT_CURSOR.get_key");
	if ((ret = cursor->get_value(cursor, &p)) != 0)
		testutil_die(ret, "WT_CURSOR.get_value");
	if (memcmp(p, big, bytes) != 0)
		testutil_die(0,
		    "retrieved big key/value item did not match original");

	/* Remove the record. */
	if ((ret = cursor->remove(cursor)) != 0)
		testutil_die(ret, "WT_CURSOR.remove");

	if ((ret = conn->close(conn, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION.close");

	big[bytes - 1] = 'a';
}
コード例 #12
0
ファイル: wtperf.c プロジェクト: niumowm/wiredtiger
void
worker(CONFIG *cfg, uint32_t worker_type)
{
	WT_CONNECTION *conn;
	WT_SESSION *session;
	WT_CURSOR *cursor;
	const char *op_name = "search";
	char *data_buf, *key_buf, *value;
	int ret, op_ret;
	uint64_t next_val;

	session = NULL;
	data_buf = key_buf = NULL;
	op_ret = 0;

	conn = cfg->conn;
	key_buf = calloc(cfg->key_sz + 1, 1);
	if (key_buf == NULL) {
		lprintf(cfg, ret = ENOMEM, 0, "Populate key buffer");
		goto err;
	}
	if (worker_type == WORKER_INSERT) {
		data_buf = calloc(cfg->data_sz, 1);
		if (data_buf == NULL) {
			lprintf(cfg, ret = ENOMEM, 0, "Populate data buffer");
			goto err;
		}
		memset(data_buf, 'a', cfg->data_sz - 1);
	}

	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) {
		lprintf(cfg, ret, 0,
		    "open_session failed in read thread");
		goto err;
	}
	if ((ret = session->open_cursor(session, cfg->uri,
	    NULL, NULL, &cursor)) != 0) {
		lprintf(cfg, ret, 0,
		    "open_cursor failed in read thread");
		goto err;
	}

	while (g_running) {
		/* Get a value in range, avoid zero. */
#define VALUE_RANGE (cfg->icount + g_nins_ops - (cfg->insert_threads + 1))
		next_val = (worker_type == WORKER_INSERT ?
		    (cfg->icount + ATOMIC_ADD(g_nins_ops, 1)) :
		    ((uint64_t)rand() % VALUE_RANGE) + 1);
		/*
		 * If the workload is started without a populate phase we
		 * rely on at least one insert to get a valid item id.
		 */
		if (worker_type != WORKER_INSERT && VALUE_RANGE < next_val)
			continue;
		sprintf(key_buf, "%0*" PRIu64, cfg->key_sz, next_val);
		cursor->set_key(cursor, key_buf);
		switch(worker_type) {
		case WORKER_READ:
			op_name = "read";
			op_ret = cursor->search(cursor);
			if (op_ret == 0)
				++g_nread_ops;
			break;
		case WORKER_INSERT:
			op_name = "insert";
			cursor->set_value(cursor, data_buf);
			op_ret = cursor->insert(cursor);
			if (op_ret != 0)
				++g_nfailedins_ops;
			break;
		case WORKER_UPDATE:
			op_name = "update";
			op_ret = cursor->search(cursor);
			if (op_ret == 0) {
				cursor->get_value(cursor, &value);
				if (value[0] == 'a')
					value[0] = 'b';
				else
					value[0] = 'a';
				op_ret = cursor->update(cursor);
			}
			if (op_ret == 0)
				++g_nupdate_ops;
			break;
		default:
			lprintf(cfg, EINVAL, 0, "Invalid worker type");
			goto err;
		}

		/* Report errors and continue. */
		if (op_ret != 0)
			lprintf(cfg, op_ret, 0,
			    "%s failed for: %s", op_name, key_buf);
		else
			++g_nworker_ops;
	}

err:	if (ret != 0)
		++g_threads_quit;
	if (session != NULL)
		session->close(session, NULL);
	if (data_buf != NULL)
		free(data_buf);
	if (key_buf != NULL)
		free(key_buf);
}
コード例 #13
0
ファイル: ex_all.c プロジェクト: ajdavis/mongo
static void
transaction_ops(WT_SESSION *session_arg)
{
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_SESSION *session;

	session = session_arg;
	conn = session->connection;

	/*! [transaction commit/rollback] */
	/*
	 * Cursors may be opened before or after the transaction begins, and in
	 * either case, subsequent operations are included in the transaction.
	 * Opening cursors before the transaction begins allows applications to
	 * cache cursors and use them for multiple operations.
	 */
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor));
	error_check(session->begin_transaction(session, NULL));

	cursor->set_key(cursor, "key");
	cursor->set_value(cursor, "value");
	switch (cursor->update(cursor)) {
	case 0:					/* Update success */
		error_check(session->commit_transaction(session, NULL));
		/*
		 * If commit_transaction succeeds, cursors remain positioned; if
		 * commit_transaction fails, the transaction was rolled-back and
		 * and all cursors are reset.
		 */
		break;
	case WT_ROLLBACK:			/* Update conflict */
	default:				/* Other error */
		error_check(session->rollback_transaction(session, NULL));
		/* The rollback_transaction call resets all cursors. */
		break;
	}

	/*
	 * Cursors remain open and may be used for multiple transactions.
	 */
	/*! [transaction commit/rollback] */
	error_check(cursor->close(cursor));

	/*! [transaction isolation] */
	/* A single transaction configured for snapshot isolation. */
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor));
	error_check(session->begin_transaction(session, "isolation=snapshot"));
	cursor->set_key(cursor, "some-key");
	cursor->set_value(cursor, "some-value");
	error_check(cursor->update(cursor));
	error_check(session->commit_transaction(session, NULL));
	/*! [transaction isolation] */

	{
	/*! [transaction prepare] */
	/*
	 * Prepare a transaction which guarantees a subsequent commit will
	 * succeed. Only commit and rollback are allowed on a transaction after
	 * it has been prepared.
	 */
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor));
	error_check(session->begin_transaction(session, NULL));
	cursor->set_key(cursor, "key");
	cursor->set_value(cursor, "value");
	error_check(session->prepare_transaction(
	    session, "prepare_timestamp=2a"));
	error_check(session->commit_transaction(
	    session, "commit_timestamp=2b"));
	/*! [transaction prepare] */
	}

	/*! [session isolation configuration] */
	/* Open a session configured for read-uncommitted isolation. */
	error_check(conn->open_session(
	    conn, NULL, "isolation=read-uncommitted", &session));
	/*! [session isolation configuration] */

	/*! [session isolation re-configuration] */
	/* Re-configure a session for snapshot isolation. */
	error_check(session->reconfigure(session, "isolation=snapshot"));
	/*! [session isolation re-configuration] */

	error_check(session->close(session, NULL));
	session = session_arg;

	{
	/*! [transaction pinned range] */
	/* Check the transaction ID range pinned by the session handle. */
	uint64_t range;

	error_check(session->transaction_pinned_range(session, &range));
	/*! [transaction pinned range] */
	}

	error_check(session->begin_transaction(session, NULL));

	{
	/*! [query timestamp] */
	char timestamp_buf[2 * sizeof(uint64_t) + 1];

	/*! [transaction timestamp] */
	error_check(
	    session->timestamp_transaction(session, "commit_timestamp=2a"));
	/*! [transaction timestamp] */

	error_check(session->commit_transaction(session, NULL));

	error_check(conn->query_timestamp(
	    conn, timestamp_buf, "get=all_committed"));
	/*! [query timestamp] */
	}

	/*! [set commit timestamp] */
	error_check(conn->set_timestamp(conn, "commit_timestamp=2a"));
	/*! [set commit timestamp] */

	/*! [set oldest timestamp] */
	error_check(conn->set_timestamp(conn, "oldest_timestamp=2a"));
	/*! [set oldest timestamp] */

	/*! [set stable timestamp] */
	error_check(conn->set_timestamp(conn, "stable_timestamp=2a"));
	/*! [set stable timestamp] */

	/*! [rollback to stable] */
	error_check(conn->rollback_to_stable(conn, NULL));
	/*! [rollback to stable] */
}
コード例 #14
0
ファイル: ex_all.c プロジェクト: ajdavis/mongo
static void
session_ops(WT_SESSION *session)
{
	WT_CONNECTION *conn;

	conn = session->connection;

	/*! [Reconfigure a session] */
	error_check(session->reconfigure(session, "isolation=snapshot"));
	/*! [Reconfigure a session] */

	/*! [Create a table] */
	error_check(session->create(session,
	    "table:mytable", "key_format=S,value_format=S"));
	/*! [Create a table] */
	error_check(session->drop(session, "table:mytable", NULL));

	/*! [Create a column-store table] */
	error_check(session->create(session,
	    "table:mytable", "key_format=r,value_format=S"));

	/*! [Alter a table] */
	error_check(session->alter(session,
	    "table:mytable", "access_pattern_hint=random"));
	/*! [Alter a table] */

	/*! [Create a column-store table] */
	error_check(session->drop(session, "table:mytable", NULL));

	/*! [Create a table with columns] */
	/*
	 * Create a table with columns: keys are record numbers, values are
	 * (string, signed 32-bit integer, unsigned 16-bit integer).
	 */
	error_check(session->create(session, "table:mytable",
	    "key_format=r,value_format=SiH,"
	    "columns=(id,department,salary,year-started)"));
	/*! [Create a table with columns] */
	error_check(session->drop(session, "table:mytable", NULL));

	/*! [Create a table and configure the page size] */
	error_check(session->create(session,
	    "table:mytable", "key_format=S,value_format=S,"
	    "internal_page_max=16KB,leaf_page_max=1MB,leaf_value_max=64KB"));
	/*! [Create a table and configure the page size] */
	error_check(session->drop(session, "table:mytable", NULL));

	/*! [Create a table and configure a large leaf value max] */
	error_check(session->create(session,
	    "table:mytable", "key_format=S,value_format=S,"
	    "leaf_page_max=16KB,leaf_value_max=256KB"));
	/*! [Create a table and configure a large leaf value max] */
	error_check(session->drop(session, "table:mytable", NULL));

	/*
	 * This example code gets run, and the compression libraries might not
	 * be loaded, causing the create to fail.  The documentation requires
	 * the code snippets, use #ifdef's to avoid running it.
	 */
#ifdef MIGHT_NOT_RUN
	/*! [Create a lz4 compressed table] */
	error_check(session->create(session,
	    "table:mytable",
	    "block_compressor=lz4,key_format=S,value_format=S"));
	/*! [Create a lz4 compressed table] */
	error_check(session->drop(session, "table:mytable", NULL));

	/*! [Create a snappy compressed table] */
	error_check(session->create(session,
	    "table:mytable",
	    "block_compressor=snappy,key_format=S,value_format=S"));
	/*! [Create a snappy compressed table] */
	error_check(session->drop(session, "table:mytable", NULL));

	/*! [Create a zlib compressed table] */
	error_check(session->create(session,
	    "table:mytable",
	    "block_compressor=zlib,key_format=S,value_format=S"));
	/*! [Create a zlib compressed table] */
	error_check(session->drop(session, "table:mytable", NULL));

	/*! [Create a zstd compressed table] */
	error_check(session->create(session,
	    "table:mytable",
	    "block_compressor=zstd,key_format=S,value_format=S"));
	/*! [Create a zstd compressed table] */
	error_check(session->drop(session, "table:mytable", NULL));
#endif

	/*! [Configure checksums to uncompressed] */
	error_check(session->create(session, "table:mytable",
	    "key_format=S,value_format=S,checksum=uncompressed"));
	/*! [Configure checksums to uncompressed] */
	error_check(session->drop(session, "table:mytable", NULL));

	/*! [Configure dictionary compression on] */
	error_check(session->create(session, "table:mytable",
	    "key_format=S,value_format=S,dictionary=1000"));
	/*! [Configure dictionary compression on] */
	error_check(session->drop(session, "table:mytable", NULL));

	/*! [Configure key prefix compression on] */
	error_check(session->create(session, "table:mytable",
	    "key_format=S,value_format=S,prefix_compression=true"));
	/*! [Configure key prefix compression on] */
	error_check(session->drop(session, "table:mytable", NULL));

#ifdef MIGHT_NOT_RUN
						/* Requires sync_file_range */
	/*! [os_cache_dirty_max configuration] */
	error_check(session->create(
	    session, "table:mytable", "os_cache_dirty_max=500MB"));
	/*! [os_cache_dirty_max configuration] */
	error_check(session->drop(session, "table:mytable", NULL));

						/* Requires posix_fadvise */
	/*! [os_cache_max configuration] */
	error_check(session->create(
	    session, "table:mytable", "os_cache_max=1GB"));
	/*! [os_cache_max configuration] */
	error_check(session->drop(session, "table:mytable", NULL));
#endif
	/*! [Configure block_allocation] */
	error_check(session->create(session, "table:mytable",
	    "key_format=S,value_format=S,block_allocation=first"));
	/*! [Configure block_allocation] */
	error_check(session->drop(session, "table:mytable", NULL));

	/*! [Create a cache-resident object] */
	error_check(session->create(
	    session, "table:mytable",
	    "key_format=r,value_format=S,cache_resident=true"));
	/*! [Create a cache-resident object] */
	error_check(session->drop(session, "table:mytable", NULL));

	{
	/* Create a table for the session operations. */
	error_check(session->create(
	    session, "table:mytable", "key_format=S,value_format=S"));

	/*! [Compact a table] */
	error_check(session->compact(session, "table:mytable", NULL));
	/*! [Compact a table] */

	/*! [Rebalance a table] */
	error_check(session->rebalance(session, "table:mytable", NULL));
	/*! [Rebalance a table] */

	error_check(session->create(
	    session, "table:old",
	    "key_format=r,value_format=S,cache_resident=true"));
	/*! [Rename a table] */
	error_check(session->rename(session, "table:old", "table:new", NULL));
	/*! [Rename a table] */

	/*! [Salvage a table] */
	error_check(session->salvage(session, "table:mytable", NULL));
	/*! [Salvage a table] */

	/*! [Truncate a table] */
	error_check(session->truncate(
	    session, "table:mytable", NULL, NULL, NULL));
	/*! [Truncate a table] */

	/*! [Transaction sync] */
	error_check(session->transaction_sync(session, NULL));
	/*! [Transaction sync] */

	/*! [Reset the session] */
	error_check(session->reset(session));
	/*! [Reset the session] */

	{
	/*
	 * Insert a pair of keys so we can truncate a range.
	 */
	WT_CURSOR *cursor;
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor));
	cursor->set_key(cursor, "June01");
	cursor->set_value(cursor, "value");
	error_check(cursor->update(cursor));
	cursor->set_key(cursor, "June30");
	cursor->set_value(cursor, "value");
	error_check(cursor->update(cursor));
	error_check(cursor->close(cursor));

	{
	/*! [Truncate a range] */
	WT_CURSOR *start, *stop;

	error_check(session->open_cursor(
	    session, "table:mytable", NULL, NULL, &start));
	start->set_key(start, "June01");
	error_check(start->search(start));

	error_check(session->open_cursor(
	    session, "table:mytable", NULL, NULL, &stop));
	stop->set_key(stop, "June30");
	error_check(stop->search(stop));

	error_check(session->truncate(session, NULL, start, stop, NULL));
	/*! [Truncate a range] */
	error_check(stop->close(stop));
	error_check(start->close(start));
	}
	}

	/*! [Upgrade a table] */
	error_check(session->upgrade(session, "table:mytable", NULL));
	/*! [Upgrade a table] */

	/*! [Verify a table] */
	error_check(session->verify(session, "table:mytable", NULL));
	/*! [Verify a table] */

	/*
	 * We can't call the backup function because it includes absolute paths
	 * for documentation purposes that don't exist on test systems.  That
	 * said, we have to reference the function to avoid build warnings
	 * about unused static code.
	 */
	(void)backup;

	/* Call other functions, where possible. */
	checkpoint_ops(session);
	error_check(cursor_ops(session));
	cursor_statistics(session);
	named_snapshot_ops(session);
	pack_ops(session);
	transaction_ops(session);

	/*! [Close a session] */
	error_check(session->close(session, NULL));
	/*! [Close a session] */

	/*
	 * We close the old session first to close all cursors, open a new one
	 * for the drop.
	 */
	error_check(conn->open_session(conn, NULL, NULL, &session));

	/*! [Drop a table] */
	error_check(session->drop(session, "table:mytable", NULL));
	/*! [Drop a table] */
	}
}
コード例 #15
0
ファイル: ex_all.c プロジェクト: ajdavis/mongo
static int
cursor_ops(WT_SESSION *session)
{
	WT_CURSOR *cursor;
	int ret;

	/*! [Open a cursor] */
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor));
	/*! [Open a cursor] */

	/*! [Open a cursor on the metadata] */
	error_check(session->open_cursor(
	    session, "metadata:", NULL, NULL, &cursor));
	/*! [Open a cursor on the metadata] */

	{
	const char *key = "some key", *value = "some value";
	/*! [Reconfigure a cursor] */
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, "overwrite=false", &cursor));

	/* Reconfigure the cursor to overwrite the record. */
	error_check(cursor->reconfigure(cursor, "overwrite=true"));

	cursor->set_key(cursor, key);
	cursor->set_value(cursor, value);
	error_check(cursor->insert(cursor));
	/*! [Reconfigure a cursor] */
	}

	{
	WT_CURSOR *duplicate;
	const char *key = "some key";
	/*! [Duplicate a cursor] */
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor));
	cursor->set_key(cursor, key);
	error_check(cursor->search(cursor));

	/* Duplicate the cursor. */
	error_check(
	    session->open_cursor(session, NULL, cursor, NULL, &duplicate));
	/*! [Duplicate a cursor] */
	}

	{
	/*! [boolean configuration string example] */
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, "overwrite", &cursor));
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, "overwrite=true", &cursor));
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, "overwrite=1", &cursor));
	/*! [boolean configuration string example] */
	}

	error_check(session->checkpoint(session, "name=midnight"));

	{
	/*! [open a named checkpoint] */
	error_check(session->open_cursor(session,
	    "table:mytable", NULL, "checkpoint=midnight", &cursor));
	/*! [open a named checkpoint] */
	}

	{
	/*! [open the default checkpoint] */
	error_check(session->open_cursor(session,
	    "table:mytable", NULL, "checkpoint=WiredTigerCheckpoint", &cursor));
	/*! [open the default checkpoint] */
	}

	{
	/*! [Set the cursor's string key] */
				/* Set the cursor's string key. */
	const char *key = "another key";
	cursor->set_key(cursor, key);
	/*! [Set the cursor's string key] */
	}

	{
	/*! [Get the cursor's string key] */
	const char *key;	/* Get the cursor's string key. */
	error_check(cursor->get_key(cursor, &key));
	/*! [Get the cursor's string key] */
	}

	/* Switch to a recno table. */
	error_check(session->create(
	    session, "table:recno", "key_format=r,value_format=S"));
	error_check(session->open_cursor(
	    session, "table:recno", NULL, NULL, &cursor));

	{
	/*! [Set the cursor's record number key] */
	uint64_t recno = 37;	/* Set the cursor's record number key. */
	cursor->set_key(cursor, recno);
	/*! [Set the cursor's record number key] */
	}

	{
	/*! [Get the cursor's record number key] */
	uint64_t recno;		/* Get the cursor's record number key. */
	error_check(cursor->get_key(cursor, &recno));
	/*! [Get the cursor's record number key] */
	}

	/* Switch to a composite table. */
	error_check(session->create(
	    session, "table:composite", "key_format=SiH,value_format=S"));
	error_check(session->open_cursor(
	    session, "table:recno", NULL, NULL, &cursor));

	{
	/*! [Set the cursor's composite key] */
			/* Set the cursor's "SiH" format composite key. */
	cursor->set_key(cursor, "first", (int32_t)5, (uint16_t)7);
	/*! [Set the cursor's composite key] */
	}

	{
	/*! [Get the cursor's composite key] */
			/* Get the cursor's "SiH" format composite key. */
	const char *first;
	int32_t second;
	uint16_t third;
	error_check(cursor->get_key(cursor, &first, &second, &third));
	/*! [Get the cursor's composite key] */
	}

	{
	/*! [Set the cursor's string value] */
				/* Set the cursor's string value. */
	const char *value = "another value";
	cursor->set_value(cursor, value);
	/*! [Set the cursor's string value] */
	}

	{
	/*! [Get the cursor's string value] */
	const char *value;	/* Get the cursor's string value. */
	error_check(cursor->get_value(cursor, &value));
	/*! [Get the cursor's string value] */
	}

	{
	/*! [Get the cursor's raw value] */
	WT_ITEM value;		/* Get the cursor's raw value. */
	error_check(cursor->get_value(cursor, &value));
	/*! [Get the cursor's raw value] */
	}

	{
	/*! [Set the cursor's raw value] */
	WT_ITEM value;		/* Set the cursor's raw value. */
	value.data = "another value";
	value.size = strlen("another value");
	cursor->set_value(cursor, &value);
	/*! [Set the cursor's raw value] */

	error_check(cursor->insert(cursor));
	}

	/*! [Return the next record] */
	error_check(cursor->next(cursor));
	/*! [Return the next record] */

	/*! [Reset the cursor] */
	error_check(cursor->reset(cursor));
	/*! [Reset the cursor] */

	/*! [Return the previous record] */
	error_check(cursor->prev(cursor));
	/*! [Return the previous record] */

	{
	WT_CURSOR *other = NULL;
	error_check(
	    session->open_cursor(session, NULL, cursor, NULL, &other));

	{
	/*! [Cursor comparison] */
	int compare;
	error_check(cursor->compare(cursor, other, &compare));
	if (compare == 0) {
		/* Cursors reference the same key */
	} else if (compare < 0) {
		/* Cursor key less than other key */
	} else if (compare > 0) {
		/* Cursor key greater than other key */
	}
	/*! [Cursor comparison] */
	}

	{
	/*! [Cursor equality] */
	int equal;
	error_check(cursor->equals(cursor, other, &equal));
	if (equal) {
		/* Cursors reference the same key */
	}
	/*! [Cursor equality] */
	}
	}

	{
	/*! [Insert a new record or overwrite an existing record] */
	/* Insert a new record or overwrite an existing record. */
	const char *key = "some key", *value = "some value";
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor));
	cursor->set_key(cursor, key);
	cursor->set_value(cursor, value);
	error_check(cursor->insert(cursor));
	/*! [Insert a new record or overwrite an existing record] */
	}

	{
	/*! [Search for an exact match] */
	const char *key = "some key";
	cursor->set_key(cursor, key);
	error_check(cursor->search(cursor));
	/*! [Search for an exact match] */
	}

	cursor_search_near(cursor);

	{
	/*! [Insert a new record and fail if the record exists] */
	/* Insert a new record and fail if the record exists. */
	const char *key = "new key", *value = "some value";
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, "overwrite=false", &cursor));
	cursor->set_key(cursor, key);
	cursor->set_value(cursor, value);
	error_check(cursor->insert(cursor));
	/*! [Insert a new record and fail if the record exists] */
	}

	error_check(session->open_cursor(
	    session, "table:recno", NULL, "append", &cursor));

	{
	/*! [Insert a new record and assign a record number] */
	/* Insert a new record and assign a record number. */
	uint64_t recno;
	const char *value = "some value";
	cursor->set_value(cursor, value);
	error_check(cursor->insert(cursor));
	error_check(cursor->get_key(cursor, &recno));
	/*! [Insert a new record and assign a record number] */
	}

	error_check(session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor));

	{
	/*! [Reserve a record] */
	const char *key = "some key";
	error_check(session->begin_transaction(session, NULL));
	cursor->set_key(cursor, key);
	error_check(cursor->reserve(cursor));
	error_check(session->commit_transaction(session, NULL));
	/*! [Reserve a record] */
	}

	error_check(session->create(
	    session, "table:blob", "key_format=S,value_format=u"));
	error_check(session->open_cursor(
	    session, "table:blob", NULL, NULL, &cursor));
	{
	WT_ITEM value;
	value.data = "abcdefghijklmnopqrstuvwxyz"
	    "abcdefghijklmnopqrstuvwxyz"
	    "abcdefghijklmnopqrstuvwxyz";
	value.size = strlen(value.data);
	cursor->set_key(cursor, "some key");
	cursor->set_value(cursor, &value);
	error_check(cursor->insert(cursor));
	}

	/* Modify requires an explicit transaction. */
	error_check(session->begin_transaction(session, NULL));
	{
	/*! [Modify an existing record] */
	WT_MODIFY entries[3];
	const char *key = "some key";

	/* Position the cursor. */
	cursor->set_key(cursor, key);
	error_check(cursor->search(cursor));

	/* Replace 20 bytes starting at byte offset 5. */
	entries[0].data.data = "some data";
	entries[0].data.size = strlen(entries[0].data.data);
	entries[0].offset = 5;
	entries[0].size = 20;

	/* Insert data at byte offset 40. */
	entries[1].data.data = "and more data";
	entries[1].data.size = strlen(entries[1].data.data);
	entries[1].offset = 40;
	entries[1].size = 0;

	/* Replace 2 bytes starting at byte offset 10. */
	entries[2].data.data = "and more data";
	entries[2].data.size = strlen(entries[2].data.data);
	entries[2].offset = 10;
	entries[2].size = 2;

	error_check(cursor->modify(cursor, entries, 3));
	/*! [Modify an existing record] */
	}
	error_check(session->commit_transaction(session, NULL));

	{
	/*! [Update an existing record or insert a new record] */
	const char *key = "some key", *value = "some value";
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor));
	cursor->set_key(cursor, key);
	cursor->set_value(cursor, value);
	error_check(cursor->update(cursor));
	/*! [Update an existing record or insert a new record] */
	}

	{
	/*! [Update an existing record and fail if DNE] */
	const char *key = "some key", *value = "some value";
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, "overwrite=false", &cursor));
	cursor->set_key(cursor, key);
	cursor->set_value(cursor, value);
	error_check(cursor->update(cursor));
	/*! [Update an existing record and fail if DNE] */
	}

	{
	/*! [Remove a record and fail if DNE] */
	const char *key = "some key";
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, "overwrite=false", &cursor));
	cursor->set_key(cursor, key);
	error_check(cursor->remove(cursor));
	/*! [Remove a record and fail if DNE] */
	}

	{
	/*! [Remove a record] */
	const char *key = "some key";
	error_check(session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor));
	cursor->set_key(cursor, key);
	error_check(cursor->remove(cursor));
	/*! [Remove a record] */
	}

	{
	/*! [Display an error] */
	const char *key = "non-existent key";
	cursor->set_key(cursor, key);
	if ((ret = cursor->remove(cursor)) != 0) {
		fprintf(stderr,
		    "cursor.remove: %s\n", wiredtiger_strerror(ret));
		return (ret);
	}
	/*! [Display an error] */
	}

	{
	/*! [Display an error thread safe] */
	const char *key = "non-existent key";
	cursor->set_key(cursor, key);
	if ((ret = cursor->remove(cursor)) != 0) {
		fprintf(stderr,
		    "cursor.remove: %s\n",
		    cursor->session->strerror(cursor->session, ret));
		return (ret);
	}
	/*! [Display an error thread safe] */
	}

	/*! [Close the cursor] */
	error_check(cursor->close(cursor));
	/*! [Close the cursor] */

	return (0);
}
コード例 #16
0
ファイル: bulk.c プロジェクト: deepinit-arek/wiredtiger
void
wts_load(void)
{
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_ITEM key, value;
	WT_SESSION *session;
	uint8_t *keybuf, *valbuf;
	int is_bulk, 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)g.wt_api->msg_printf(g.wt_api, session,
		    "=============== bulk load start ===============");

	/*
	 * Avoid bulk load with KVS (there's no bulk load support for a
	 * data-source); avoid bulk load with a custom collator, because
	 * the order of insertion will not match the collation order.
	 */
	is_bulk = !g.c_reverse &&
	    !DATASOURCE("kvsbdb") && !DATASOURCE("helium");
	if ((ret = session->open_cursor(session, g.uri, NULL,
	    is_bulk ? "bulk" : NULL, &cursor)) != 0)
		die(ret, "session.open_cursor");

	/* Set up the default key buffer. */
	key_gen_setup(&keybuf);
	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 (!is_bulk)
				cursor->set_key(cursor, g.key_cnt);
			cursor->set_value(cursor, *(uint8_t *)value.data);
			if (g.logging == LOG_OPS)
				(void)g.wt_api->msg_printf(g.wt_api, session,
				    "%-10s %" PRIu32 " {0x%02" PRIx8 "}",
				    "bulk V",
				    g.key_cnt, ((uint8_t *)value.data)[0]);
			break;
		case VAR:
			if (!is_bulk)
				cursor->set_key(cursor, g.key_cnt);
			cursor->set_value(cursor, &value);
			if (g.logging == LOG_OPS)
				(void)g.wt_api->msg_printf(g.wt_api, 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)g.wt_api->msg_printf(g.wt_api, 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)g.wt_api->msg_printf(g.wt_api, 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)g.wt_api->msg_printf(g.wt_api, session,
		    "=============== bulk load stop ===============");

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

	free(keybuf);
	free(valbuf);
}
コード例 #17
0
int main(void)
{
	int count, exact, ret;
	WT_CONNECTION *conn;
	WT_SESSION *session;
	WT_CURSOR *cursor;
	CUSTOMER cust, *custp, cust_sample[] = {
		{ 0, "Professor Oak", "LeafGreen Avenue", "123-456-7890" },
		{ 0, "Lorelei", "Sevii Islands", "098-765-4321" },
		{ 0, NULL, NULL, NULL }
	};
	CALL call, *callp, call_sample[] = {
		{ 0, 32, 1, 2, "billing", "unavailable" },
		{ 0, 33, 1, 2, "billing", "available" },
		{ 0, 34, 1, 2, "reminder", "unavailable" },
		{ 0, 35, 1, 2, "reminder", "available" },
		{ 0, 0, 0, 0, NULL, NULL }
	};

	ret = wiredtiger_open(home, NULL, "create", &conn);
	if (ret != 0) {
		fprintf(stderr, "Error connecting to %s: %s\n",
		    home, wiredtiger_strerror(ret));
		return (1);
	}
	/* Note: further error checking omitted for clarity. */

	/*! [call-center work] */
	ret = conn->open_session(conn, NULL, NULL, &session);

	/*
	 * Create the customers table, give names and types to the columns.
	 * The columns will be stored in two groups: "main" and "address",
	 * created below.
	 */
	ret = session->create(session, "table:customers",
	    "key_format=r,"
	    "value_format=SSS,"
	    "columns=(id,name,address,phone),"
	    "colgroups=(main,address)");

	/* Create the main column group with value columns except address. */
	ret = session->create(session,
	    "colgroup:customers:main", "columns=(name,phone)");

	/* Create the address column group with just the address. */
	ret = session->create(session,
	    "colgroup:customers:address", "columns=(address)");

	/* Create an index on the customer table by phone number. */
	ret = session->create(session,
	    "index:customers:phone", "columns=(phone)");

	/* Populate the customers table with some data. */
	ret = session->open_cursor(
	    session, "table:customers", NULL, "append", &cursor);
	for (custp = cust_sample; custp->name != NULL; custp++) {
		cursor->set_value(cursor,
		    custp->name, custp->address, custp->phone);
		ret = cursor->insert(cursor);
	}
	ret = cursor->close(cursor);

	/*
	 * Create the calls table, give names and types to the columns.  All the
	 * columns will be stored together, so no column groups are declared.
	 */
	ret = session->create(session, "table:calls",
	    "key_format=r,"
	    "value_format=qrrSS,"
	    "columns=(id,call_date,cust_id,emp_id,call_type,notes)");

	/*
	 * Create an index on the calls table with a composite key of cust_id
	 * and call_date.
	 */
	ret = session->create(session, "index:calls:cust_date",
	    "columns=(cust_id,call_date)");

	/* Populate the calls table with some data. */
	ret = session->open_cursor(
	    session, "table:calls", NULL, "append", &cursor);
	for (callp = call_sample; callp->call_type != NULL; callp++) {
		cursor->set_value(cursor, callp->call_date, callp->cust_id,
		    callp->emp_id, callp->call_type, callp->notes);
		ret = cursor->insert(cursor);
	}
	ret = cursor->close(cursor);

	/*
	 * First query: a call arrives.  In SQL:
	 *
	 * SELECT id, name FROM Customers WHERE phone=?
	 *
	 * Use the cust_phone index, lookup by phone number to fill the
	 * customer record.  The cursor will have a key format of "S" for a
	 * string because the cust_phone index has a single column ("phone"),
	 * which is of type "S".
	 *
	 * Specify the columns we want: the customer ID and the name.  This
	 * means the cursor's value format will be "rS".
	 */
	ret = session->open_cursor(session,
	    "index:customers:phone(id,name)", NULL, NULL, &cursor);
	cursor->set_key(cursor, "123-456-7890");
	ret = cursor->search(cursor);
	if (ret == 0) {
		ret = cursor->get_value(cursor, &cust.id, &cust.name);
		printf("Read customer record for %s (ID %" PRIu64 ")\n",
		    cust.name, cust.id);
	}
	ret = cursor->close(cursor);

	/*
	 * Next query: get the recent order history.  In SQL:
	 *
	 * SELECT * FROM Calls WHERE cust_id=? ORDER BY call_date DESC LIMIT 3
	 *
	 * Use the call_cust_date index to find the matching calls.  Since it is
	 * is in increasing order by date for a given customer, we want to start
	 * with the last record for the customer and work backwards.
	 *
	 * Specify a subset of columns to be returned.  (Note that if these were
	 * all covered by the index, the primary would not have to be accessed.)
	 * Stop after getting 3 records.
	 */
	ret = session->open_cursor(session,
	    "index:calls:cust_date(cust_id,call_type,notes)",
	    NULL, NULL, &cursor);

	/*
	 * The keys in the index are (cust_id,call_date) -- we want the largest
	 * call date for a given cust_id.  Search for (cust_id+1,0), then work
	 * backwards.
	 */
	cust.id = 1;
	cursor->set_key(cursor, cust.id + 1, 0);
	ret = cursor->search_near(cursor, &exact);

	/*
	 * If the table is empty, search_near will return WT_NOTFOUND, else the
	 * cursor will be positioned on a matching key if one exists, or an
	 * adjacent key if one does not.  If the positioned key is equal to or
	 * larger than the search key, go back one.
	 */
	if (ret == 0 && exact >= 0)
		ret = cursor->prev(cursor);
	for (count = 0; ret == 0 && count < 3; ++count) {
		ret = cursor->get_value(cursor,
		    &call.cust_id, &call.call_type, &call.notes);
		if (call.cust_id != cust.id)
			break;
		printf("Call record: customer %" PRIu64 " (%s: %s)\n",
		    call.cust_id, call.call_type, call.notes);
		ret = cursor->prev(cursor);
	}
	/*! [call-center work] */

	ret = conn->close(conn, NULL);

	return (ret);
}
コード例 #18
0
ファイル: ex_test_perf.c プロジェクト: zhliu03/wiredtiger
int populate(CONFIG *cfg)
{
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_SESSION *session;
	char *data_buf, *key_buf;
	double secs;
	int ret;
	struct timeval e;

	conn = cfg->conn;

	cfg->phase = LSM_TEST_PERF_POP;
	if (cfg->verbose > 0)
		fprintf(cfg->logf, "Starting bulk load\n");

	data_buf = calloc(cfg->data_sz, 1);
	if (data_buf == NULL)
		return (ENOMEM);
	key_buf = calloc(cfg->key_sz, 1);
	if (key_buf == NULL)
		return (ENOMEM);

	/* Open a session for the current thread's work. */
	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) {
		fprintf(stderr, "Error opening a session on %s: %s\n",
		    cfg->home, wiredtiger_strerror(ret));
		return (ret);
	}

	if ((ret = session->create(
	    session, cfg->uri, cfg->table_config)) != 0) {
		fprintf(stderr, "Error creating table %s: %s\n",
		    cfg->uri, wiredtiger_strerror(ret));
		return (ret);
	}

	if ((ret = session->open_cursor(
	    session, cfg->uri, NULL, "bulk", &cursor)) != 0) {
		fprintf(stderr, "Error opening cursor %s: %s\n",
		    cfg->uri, wiredtiger_strerror(ret));
		return (ret);
	}

	memset(data_buf, 'a', cfg->data_sz - 1);
	cursor->set_value(cursor, data_buf);
	/* Populate the database. */
	gettimeofday(&cfg->phase_start_time, NULL);
	for (nops = 0; nops < cfg->icount; nops++) {
		if (cfg->verbose > 0) {
			if (nops % 1000000 == 0)
				printf(".");
			if (nops % 50000000 == 0)
				printf("\n");
		}
		sprintf(key_buf, "%"PRIu64, nops);
		cursor->set_key(cursor, key_buf);
		if ((ret = cursor->insert(cursor)) != 0) {
			fprintf(stderr, "Failed inserting with: %d\n", ret);
			return (ret);
		}
	}
	gettimeofday(&e, NULL);
	cursor->close(cursor);
	session->close(session, NULL);
	if (cfg->verbose > 0) {
		fprintf(cfg->logf,
		    "Finished bulk load of %d items\n", cfg->icount);
		secs = e.tv_sec + e.tv_usec / 1000000.0;
		secs -= (cfg->phase_start_time.tv_sec +
		    cfg->phase_start_time.tv_usec / 1000000.0);
		if (secs == 0)
			++secs;
		fprintf(cfg->logf,
		    "Load time: %.2f\n" "load ops/sec: %.2f\n",
		    secs, cfg->icount / secs);
	}

	free(data_buf);
	free(key_buf);
	return (ret);
}
コード例 #19
0
ファイル: salvage.c プロジェクト: qixin/wiredtiger
/*
 * build --
 *	Build a row- or column-store page in a file.
 */
void
build(int ikey, int ivalue, int cnt)
{
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_ITEM key, value;
	WT_SESSION *session;
	char config[256], kbuf[64], vbuf[64];
	int new_slvg;

	assert(wiredtiger_open(NULL, NULL, "create", &conn) == 0);
	assert(conn->open_session(conn, NULL, NULL, &session) == 0);
	assert(session->drop(session, "file:" LOAD, "force") == 0);

	switch (page_type) {
	case WT_PAGE_COL_FIX:
		(void)snprintf(config, sizeof(config),
		    "key_format=r,value_format=7t,"
		    "allocation_size=%d,"
		    "internal_page_max=%d,internal_item_max=%d,"
		    "leaf_page_max=%d,leaf_item_max=%d",
		    PSIZE, PSIZE, OSIZE, PSIZE, OSIZE);
		break;
	case WT_PAGE_COL_VAR:
		(void)snprintf(config, sizeof(config),
		    "key_format=r,"
		    "allocation_size=%d,"
		    "internal_page_max=%d,internal_item_max=%d,"
		    "leaf_page_max=%d,leaf_item_max=%d",
		    PSIZE, PSIZE, OSIZE, PSIZE, OSIZE);
		break;
	case WT_PAGE_ROW_LEAF:
		(void)snprintf(config, sizeof(config),
		    "key_format=u,"
		    "allocation_size=%d,"
		    "internal_page_max=%d,internal_item_max=%d,"
		    "leaf_page_max=%d,leaf_item_max=%d",
		    PSIZE, PSIZE, OSIZE, PSIZE, OSIZE);
		break;
	default:
		assert(0);
	}
	assert(session->create(session, "file:" LOAD, config) == 0);
	assert(session->open_cursor(
	    session, "file:" LOAD, NULL, "bulk", &cursor) == 0);
	for (; cnt > 0; --cnt, ++ikey, ++ivalue) {
		switch (page_type) {			/* Build the key. */
		case WT_PAGE_COL_FIX:
		case WT_PAGE_COL_VAR:
			break;
		case WT_PAGE_ROW_LEAF:
			snprintf(kbuf, sizeof(kbuf), "%010d KEY------", ikey);
			key.data = kbuf;
			key.size = 20;
			cursor->set_key(cursor, &key);
			break;
		}

		switch (page_type) {			/* Build the value. */
		case WT_PAGE_COL_FIX:
			cursor->set_value(cursor, ivalue & 0x7f);
			break;
		case WT_PAGE_COL_VAR:
		case WT_PAGE_ROW_LEAF:
			snprintf(vbuf, sizeof(vbuf),
			    "%010d VALUE----", value_unique ? ivalue : 37);
			value.data = vbuf;
			value.size = 20;
			cursor->set_value(cursor, &value);
		}
		assert(cursor->insert(cursor) == 0);
	}

	/*
	 * The first time through this routine we put a matching configuration
	 * in for the salvage file.
	 */
	new_slvg = (access(SLVG, F_OK) != 0);
	if (new_slvg) {
		assert(session->drop(session, "file:" SLVG, "force") == 0);
		assert(session->create(session, "file:" SLVG, config) == 0);
	}

	assert(conn->close(conn, 0) == 0);

	/*
	 * We created the salvage file above, but all we want is the schema,
	 * we're creating the salvage file by hand.
	 */
	if (new_slvg)
		(void)remove(SLVG);
}
コード例 #20
0
ファイル: ex_access.c プロジェクト: AlexOreshkevich/mongo
int
main(void)
{
	/*! [access example connection] */
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_SESSION *session;
	const char *key, *value;
	int ret;

	/*
	 * Create a clean test directory for this run of the test program if the
	 * environment variable isn't already set (as is done by make check).
	 */
	if (getenv("WIREDTIGER_HOME") == NULL) {
		home = "WT_HOME";
		ret = system("rm -rf WT_HOME && mkdir WT_HOME");
	} else
		home = NULL;

	/* Open a connection to the database, creating it if necessary. */
	if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0 ||
	    (ret = conn->open_session(conn, NULL, NULL, &session)) != 0) {
		fprintf(stderr, "Error connecting to %s: %s\n",
		    home, wiredtiger_strerror(ret));
		return (ret);
	}
	/*! [access example connection] */

	/*! [access example table create] */
	ret = session->create(session,
	    "table:access", "key_format=S,value_format=S");
	/*! [access example table create] */

	/*! [access example cursor open] */
	ret = session->open_cursor(session,
	    "table:access", NULL, NULL, &cursor);
	/*! [access example cursor open] */

	/*! [access example cursor insert] */
	cursor->set_key(cursor, "key1");	/* Insert a record. */
	cursor->set_value(cursor, "value1");
	ret = cursor->insert(cursor);
	/*! [access example cursor insert] */

	/*! [access example cursor list] */
	ret = cursor->reset(cursor);	        /* Restart the scan. */
	while ((ret = cursor->next(cursor)) == 0) {
		ret = cursor->get_key(cursor, &key);
		ret = cursor->get_value(cursor, &value);

		printf("Got record: %s : %s\n", key, value);
	}
	/*! [access example cursor list] */

	/*! [access example close] */
	ret = conn->close(conn, NULL);
	/*! [access example close] */

	return (ret);
}
コード例 #21
0
ファイル: main.c プロジェクト: jbreams/mongo
int
main(int argc, char *argv[])
{
	TEST_OPTS *opts, _opts;
	WT_CURSOR *c;
	WT_SESSION *session;
	clock_t ce, cs;
	pthread_t id[100];
	uint64_t current_value;
	int i;

	opts = &_opts;
	if (testutil_disable_long_tests())
		return (0);
	memset(opts, 0, sizeof(*opts));
	opts->nthreads = 10;
	opts->nrecords = 1000;
	opts->table_type = TABLE_ROW;
	testutil_check(testutil_parse_opts(argc, argv, opts));
	testutil_make_work_dir(opts->home);

	testutil_check(wiredtiger_open(opts->home, NULL,
	    "create,"
	    "cache_size=2G,"
	    "eviction=(threads_max=5),"
	    "statistics=(fast)", &opts->conn));
	testutil_check(
	    opts->conn->open_session(opts->conn, NULL, NULL, &session));
	testutil_check(session->create(session, opts->uri,
	    "key_format=Q,value_format=Q,"
	    "leaf_page_max=32k,"));

	/* Create the single record. */
	testutil_check(
	    session->open_cursor(session, opts->uri, NULL, NULL, &c));
	c->set_key(c, 1);
	c->set_value(c, 0);
	testutil_check(c->insert(c));
	testutil_check(c->close(c));
	cs = clock();
	for (i = 0; i < (int)opts->nthreads; ++i) {
		testutil_check(pthread_create(
		    &id[i], NULL, thread_insert_race, (void *)opts));
	}
	while (--i >= 0)
		testutil_check(pthread_join(id[i], NULL));
	testutil_check(
	    session->open_cursor(session, opts->uri, NULL, NULL, &c));
	c->set_key(c, 1);
	testutil_check(c->search(c));
	testutil_check(c->get_value(c, &current_value));
	if (current_value != opts->nthreads * opts->nrecords) {
		fprintf(stderr,
		    "ERROR: didn't get expected number of changes\n");
		fprintf(stderr, "got: %" PRIu64 ", expected: %" PRIu64 "\n",
		    current_value, opts->nthreads * opts->nrecords);
		return (EXIT_FAILURE);
	}
	testutil_check(session->close(session, NULL));
	ce = clock();
	printf("%" PRIu64 ": %.2lf\n",
	    opts->nrecords, (ce - cs) / (double)CLOCKS_PER_SEC);

	testutil_cleanup(opts);
	return (EXIT_SUCCESS);
}
コード例 #22
0
ファイル: ex_schema.c プロジェクト: zhliu03/wiredtiger
int main(void)
{
	int ret;
	WT_CONNECTION *conn;
	WT_SESSION *session;
	WT_CURSOR *cursor;
	POP_RECORD *p, *endp;
	const char *country;
	uint64_t recno;
	uint16_t year;

	ret = wiredtiger_open(home, NULL, "create", &conn);
	if (ret != 0)
		fprintf(stderr, "Error connecting to %s: %s\n",
		    home, wiredtiger_strerror(ret));
	/* Note: error checking omitted for clarity. */

	/*! [schema work] */
	ret = conn->open_session(conn, NULL, NULL, &session);

	/*
	 * Create the population table.
	 * Keys are record numbers, the format for values is
	 * (5-byte string, short, long).
	 * See ::wiredtiger_struct_pack for details of the format strings.
	 *
	 * If this program is run multiple times so the table already exists,
	 * this call will verify that the table exists.  It is not required in
	 * that case, but is a safety check that the schema matches what the
	 * program expects.
	 */
	ret = session->create(session, "table:population",
	    "key_format=r,"
	    "value_format=5sHQ,"
	    "columns=(id,country,year,population),"
	    "colgroups=(main,population)");

	/* Create the column groups to store population in its own file. */
	ret = session->create(session, "colgroup:population:main",
	    "columns=(country,year)");

	ret = session->create(session, "colgroup:population:population",
	    "columns=(population)");

	/* Create an index with composite key (country,year). */
	ret = session->create(session, "index:population:country_year",
	    "columns=(country,year)");

	ret = session->open_cursor(session, "table:population",
	    NULL, "append", &cursor);

	endp = pop_data + (sizeof (pop_data) / sizeof(pop_data[0]));
	for (p = pop_data; p < endp; p++) {
		cursor->set_value(cursor, p->country, p->year, p->population);
		ret = cursor->insert(cursor);
	}
	ret = cursor->close(cursor);

	/* Now just read through the countries we know about */
	ret = session->open_cursor(session,
	    "index:population:country_year(id)",
	    NULL, NULL, &cursor);

	while ((ret = cursor->next(cursor)) == 0) {
		cursor->get_key(cursor, &country, &year);
		cursor->get_value(cursor, &recno);

		printf("Got country %s : row ID %d\n", country, (int)recno);
	}

	ret = conn->close(conn, NULL);
	/*! [schema work] */

	return (ret);
}
コード例 #23
0
ファイル: salvage.c プロジェクト: Machyne/mongo
/*
 * build --
 *	Build a row- or column-store page in a file.
 */
void
build(int ikey, int ivalue, int cnt)
{
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_ITEM key, value;
	WT_SESSION *session;
	char config[256], kbuf[64], vbuf[64];
	int new_slvg;

	/*
	 * Disable logging: we're modifying files directly, we don't want to
	 * run recovery.
	 */
	CHECK(wiredtiger_open(
	    NULL, NULL, "create,log=(enabled=false)", &conn) == 0);
	CHECK(conn->open_session(conn, NULL, NULL, &session) == 0);
	CHECK(session->drop(session, "file:" LOAD, "force") == 0);

	switch (page_type) {
	case WT_PAGE_COL_FIX:
		(void)snprintf(config, sizeof(config),
		    "key_format=r,value_format=7t,"
		    "allocation_size=%d,"
		    "internal_page_max=%d,internal_item_max=%d,"
		    "leaf_page_max=%d,leaf_item_max=%d",
		    PSIZE, PSIZE, OSIZE, PSIZE, OSIZE);
		break;
	case WT_PAGE_COL_VAR:
		(void)snprintf(config, sizeof(config),
		    "key_format=r,"
		    "allocation_size=%d,"
		    "internal_page_max=%d,internal_item_max=%d,"
		    "leaf_page_max=%d,leaf_item_max=%d",
		    PSIZE, PSIZE, OSIZE, PSIZE, OSIZE);
		break;
	case WT_PAGE_ROW_LEAF:
		(void)snprintf(config, sizeof(config),
		    "key_format=u,"
		    "allocation_size=%d,"
		    "internal_page_max=%d,internal_item_max=%d,"
		    "leaf_page_max=%d,leaf_item_max=%d",
		    PSIZE, PSIZE, OSIZE, PSIZE, OSIZE);
		break;
	default:
		assert(0);
	}
	CHECK(session->create(session, "file:" LOAD, config) == 0);
	CHECK(session->open_cursor(
	    session, "file:" LOAD, NULL, "bulk,append", &cursor) == 0);
	for (; cnt > 0; --cnt, ++ikey, ++ivalue) {
		switch (page_type) {			/* Build the key. */
		case WT_PAGE_COL_FIX:
		case WT_PAGE_COL_VAR:
			break;
		case WT_PAGE_ROW_LEAF:
			snprintf(kbuf, sizeof(kbuf), "%010d KEY------", ikey);
			key.data = kbuf;
			key.size = 20;
			cursor->set_key(cursor, &key);
			break;
		}

		switch (page_type) {			/* Build the value. */
		case WT_PAGE_COL_FIX:
			cursor->set_value(cursor, ivalue & 0x7f);
			break;
		case WT_PAGE_COL_VAR:
		case WT_PAGE_ROW_LEAF:
			snprintf(vbuf, sizeof(vbuf),
			    "%010d VALUE----", value_unique ? ivalue : 37);
			value.data = vbuf;
			value.size = 20;
			cursor->set_value(cursor, &value);
		}
		CHECK(cursor->insert(cursor) == 0);
	}

	/*
	 * The first time through this routine we create the salvage file and
	 * then remove it (all we want is the appropriate schema entry, we're
	 * creating the salvage file itself by hand).
	 */
	new_slvg = !file_exists(SLVG);
	if (new_slvg) {
		CHECK(session->drop(session, "file:" SLVG, "force") == 0);
		CHECK(session->create(session, "file:" SLVG, config) == 0);
	}
	CHECK(conn->close(conn, 0) == 0);
	if (new_slvg)
		(void)remove(SLVG);
}
コード例 #24
0
ファイル: wtperf.c プロジェクト: umerazad/wiredtiger
void
worker(CONFIG *cfg, uint32_t worker_type)
{
	WT_CONNECTION *conn;
	WT_SESSION *session;
	WT_CURSOR *cursor;
	const char *op_name = "search";
	char *data_buf, *key_buf, *value;
	int ret, op_ret;
	uint64_t next_incr, next_val;

	session = NULL;
	data_buf = key_buf = NULL;
	op_ret = 0;

	conn = cfg->conn;
	key_buf = calloc(cfg->key_sz + 1, 1);
	if (key_buf == NULL) {
		lprintf(cfg, ret = ENOMEM, 0, "Populate key buffer");
		goto err;
	}
	if (worker_type == WORKER_INSERT || worker_type == WORKER_UPDATE) {
		data_buf = calloc(cfg->data_sz, 1);
		if (data_buf == NULL) {
			lprintf(cfg, ret = ENOMEM, 0, "Populate data buffer");
			goto err;
		}
		memset(data_buf, 'a', cfg->data_sz - 1);
	}

	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) {
		lprintf(cfg, ret, 0,
		    "open_session failed in read thread");
		goto err;
	}
	if ((ret = session->open_cursor(session, cfg->uri,
	    NULL, NULL, &cursor)) != 0) {
		lprintf(cfg, ret, 0,
		    "open_cursor failed in read thread");
		goto err;
	}

	while (g_running) {
		/* Get a value in range, avoid zero. */
		if (worker_type == WORKER_INSERT)
			next_incr = ATOMIC_ADD(g_nins_ops, 1);

		if (!F_ISSET(cfg, PERF_RAND_WORKLOAD) &&
		    worker_type == WORKER_INSERT)
			next_val = cfg->icount + next_incr;
		else
			next_val = wtperf_rand(cfg);
		/*
		 * If the workload is started without a populate phase we
		 * rely on at least one insert to get a valid item id.
		 */
		if (worker_type != WORKER_INSERT &&
		    wtperf_value_range(cfg) < next_val)
			continue;
		sprintf(key_buf, "%0*" PRIu64, cfg->key_sz, next_val);
		cursor->set_key(cursor, key_buf);
		switch(worker_type) {
		case WORKER_READ:
			op_name = "read";
			op_ret = cursor->search(cursor);
			if (F_ISSET(cfg, PERF_RAND_WORKLOAD) &&
			    op_ret == WT_NOTFOUND)
				op_ret = 0;
			if (op_ret == 0)
				++g_nread_ops;
			break;
		case WORKER_INSERT_RMW:
			op_name="insert_rmw";
			op_ret = cursor->search(cursor);
			if (op_ret != WT_NOTFOUND)
				break;
			/* Fall through */
		case WORKER_INSERT:
			op_name = "insert";
			cursor->set_value(cursor, data_buf);
			op_ret = cursor->insert(cursor);
			if (F_ISSET(cfg, PERF_RAND_WORKLOAD) &&
			    op_ret == WT_DUPLICATE_KEY)
				op_ret = 0;
			if (op_ret != 0)
				++g_nfailedins_ops;
			break;
		case WORKER_UPDATE:
			op_name = "update";
			op_ret = cursor->search(cursor);
			if (op_ret == 0) {
				cursor->get_value(cursor, &value);
				memcpy(data_buf, value, cfg->data_sz);
				if (data_buf[0] == 'a')
					data_buf[0] = 'b';
				else
					data_buf[0] = 'a';
				cursor->set_value(cursor, data_buf);
				op_ret = cursor->update(cursor);
			}
			if (F_ISSET(cfg, PERF_RAND_WORKLOAD) &&
			    op_ret == WT_NOTFOUND)
				op_ret = 0;
			if (op_ret == 0)
				++g_nupdate_ops;
			break;
		default:
			lprintf(cfg, EINVAL, 0, "Invalid worker type");
			goto err;
		}

		/* Report errors and continue. */
		if (op_ret != 0)
			lprintf(cfg, op_ret, 0,
			    "%s failed for: %s", op_name, key_buf);
		else
			++g_nworker_ops;
	}

err:	if (ret != 0)
		++g_threads_quit;
	if (session != NULL)
		session->close(session, NULL);
	if (data_buf != NULL)
		free(data_buf);
	if (key_buf != NULL)
		free(key_buf);
}
コード例 #25
0
ファイル: main.c プロジェクト: ajdavis/mongo
int
main(int argc, char *argv[])
{
	TEST_OPTS *opts, _opts;
	WT_CURSOR *balancecur, *flagcur, *joincur, *postcur;
	WT_CURSOR *maincur;
	WT_SESSION *session;
	int balance, count, flag, key, key2, post, ret;
	char balanceuri[256];
	char cfg[128];
	char flaguri[256];
	char joinuri[256];
	char posturi[256];
	const char *tablename;

	opts = &_opts;
	memset(opts, 0, sizeof(*opts));
	testutil_check(testutil_parse_opts(argc, argv, opts));
	testutil_make_work_dir(opts->home);
	testutil_progress(opts, "start");

	testutil_check(wiredtiger_open(opts->home, NULL,
	    "create,cache_size=250M", &opts->conn));
	testutil_progress(opts, "wiredtiger_open");
	testutil_check(
	    opts->conn->open_session(opts->conn, NULL, NULL, &session));
	testutil_progress(opts, "sessions opened");

	/*
	 * Note: repeated primary key 'id' as 'id2'.  This makes
	 * it easier to dump an index and know which record we're
	 * looking at.
	 */
	testutil_check(session->create(session, opts->uri,
	    "key_format=i,value_format=iiii,"
	    "columns=(id,post,balance,flag,id2)"));

	tablename = strchr(opts->uri, ':');
	testutil_assert(tablename != NULL);
	tablename++;
	testutil_check(__wt_snprintf(
	    posturi, sizeof(posturi), "index:%s:post", tablename));
	testutil_check(__wt_snprintf(
	    balanceuri, sizeof(balanceuri), "index:%s:balance", tablename));
	testutil_check(__wt_snprintf(
	    flaguri, sizeof(flaguri), "index:%s:flag", tablename));
	testutil_check(__wt_snprintf(
	    joinuri, sizeof(joinuri), "join:%s", opts->uri));

	testutil_check(session->create(session, posturi, "columns=(post)"));
	testutil_check(session->create(session, balanceuri,
	    "columns=(balance)"));
	testutil_check(session->create(session, flaguri, "columns=(flag)"));
	testutil_progress(opts, "setup complete");

	/*
	 * Insert a single record with all items we are search for,
	 * this makes our logic easier.
	 */
	testutil_check(session->open_cursor(session, opts->uri, NULL, NULL,
	    &maincur));
	maincur->set_key(maincur, N_RECORDS);
	maincur->set_value(maincur, 54321, 0, "", 0, N_RECORDS);
	testutil_check(maincur->insert(maincur));
	testutil_check(maincur->close(maincur));
	testutil_check(session->close(session, NULL));

	testutil_progress(opts, "populate start");
	populate(opts);
	testutil_progress(opts, "populate end");

	testutil_check(opts->conn->open_session(
	    opts->conn, NULL, NULL, &session));

	testutil_check(session->open_cursor(session,
	    posturi, NULL, NULL, &postcur));
	testutil_check(session->open_cursor(session,
	    balanceuri, NULL, NULL, &balancecur));
	testutil_check(session->open_cursor(session,
	    flaguri, NULL, NULL, &flagcur));
	testutil_check(session->open_cursor(session,
	    joinuri, NULL, NULL, &joincur));

	postcur->set_key(postcur, 54321);
	testutil_check(postcur->search(postcur));
	testutil_check(session->join(session, joincur, postcur,
	    "compare=eq"));

	balancecur->set_key(balancecur, 0);
	testutil_check(balancecur->search(balancecur));
	testutil_check(__wt_snprintf(cfg, sizeof(cfg),
	    "compare=lt,strategy=bloom,count=%d", N_RECORDS / 100));
	testutil_check(session->join(session, joincur, balancecur, cfg));

	flagcur->set_key(flagcur, 0);
	testutil_check(flagcur->search(flagcur));
	testutil_check(__wt_snprintf(cfg, sizeof(cfg),
	    "compare=eq,strategy=bloom,count=%d", N_RECORDS / 100));
	testutil_check(session->join(session, joincur, flagcur, cfg));

	/* Expect no values returned */
	count = 0;
	while ((ret = joincur->next(joincur)) == 0) {
		/*
		 * The values may already have been changed, but
		 * print them for informational purposes.
		 */
		testutil_check(joincur->get_key(joincur, &key));
		testutil_check(joincur->get_value(joincur, &post,
		    &balance, &flag, &key2));
		fprintf(stderr, "FAIL: "
		    "key=%d/%d, postal_code=%d, balance=%d, flag=%d\n",
		    key, key2, post, balance, flag);
		count++;
	}
	testutil_assert(ret == WT_NOTFOUND);
	testutil_assert(count == 0);

	testutil_progress(opts, "cleanup starting");
	testutil_cleanup(opts);
	return (EXIT_SUCCESS);
}
コード例 #26
0
ファイル: wtperf.c プロジェクト: umerazad/wiredtiger
void *
populate_thread(void *arg)
{
	CONFIG *cfg;
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_SESSION *session;
	char *data_buf, *key_buf;
	int ret;
	uint64_t op;

	cfg = (CONFIG *)arg;
	conn = cfg->conn;
	session = NULL;
	data_buf = key_buf = NULL;

	cfg->phase = WT_PERF_POP;

	data_buf = calloc(cfg->data_sz, 1);
	if (data_buf == NULL) {
		lprintf(cfg, ENOMEM, 0, "Populate data buffer");
		goto err;
	}
	key_buf = calloc(cfg->key_sz + 1, 1);
	if (key_buf == NULL) {
		lprintf(cfg, ENOMEM, 0, "Populate key buffer");
		goto err;
	}

	/* Open a session for the current thread's work. */
	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) {
		lprintf(cfg, ret, 0,
		    "Error opening a session on %s", cfg->home);
		goto err;
	}

	/* Do a bulk load if populate is single-threaded. */
	if ((ret = session->open_cursor(
	    session, cfg->uri, NULL,
	    cfg->populate_threads == 1 ? "bulk" : NULL,
	    &cursor)) != 0) {
		lprintf(cfg, ret, 0, "Error opening cursor %s", cfg->uri);
		goto err;
	}

	memset(data_buf, 'a', cfg->data_sz - 1);
	cursor->set_value(cursor, data_buf);
	/* Populate the database. */
	while (1) {
		get_next_op(&op);
		if (op > cfg->icount)
			break;
		sprintf(key_buf, "%0*" PRIu64, cfg->key_sz, op);
		cursor->set_key(cursor, key_buf);
		if ((ret = cursor->insert(cursor)) != 0) {
			lprintf(cfg, ret, 0, "Failed inserting");
			goto err;
		}
	}
	/* To ensure managing thread knows if we exited early. */
err:	if (ret != 0)
		++g_threads_quit;
	if (session != NULL)
		session->close(session, NULL);
	if (data_buf)
		free(data_buf);
	if (key_buf)
		free(key_buf);
	return (arg);
}
コード例 #27
0
ファイル: ex_all.c プロジェクト: ezhangle/node-wiredtiger
int
cursor_ops(WT_SESSION *session)
{
	WT_CURSOR *cursor;
	int ret;

	/*! [Open a cursor] */
	ret = session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor);
	/*! [Open a cursor] */

	/*! [Open a cursor on the metadata] */
	ret = session->open_cursor(
	    session, "metadata:", NULL, NULL, &cursor);
	/*! [Open a cursor on the metadata] */

	{
	WT_CURSOR *duplicate;
	const char *key = "some key";
	/*! [Duplicate a cursor] */
	ret = session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor);
	cursor->set_key(cursor, key);
	ret = cursor->search(cursor);

	/* Duplicate the cursor. */
	ret = session->open_cursor(session, NULL, cursor, NULL, &duplicate);
	/*! [Duplicate a cursor] */
	}

	{
	WT_CURSOR *overwrite_cursor;
	const char *key = "some key", *value = "some value";
	/*! [Reconfigure a cursor] */
	ret = session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor);
	cursor->set_key(cursor, key);

	/* Reconfigure the cursor to overwrite the record. */
	ret = session->open_cursor(
	    session, NULL, cursor, "overwrite", &overwrite_cursor);
	ret = cursor->close(cursor);

	overwrite_cursor->set_value(overwrite_cursor, value);
	ret = overwrite_cursor->insert(cursor);
	/*! [Reconfigure a cursor] */
	}

	{
	/*! [boolean configuration string example] */
	ret = session->open_cursor(session, "table:mytable", NULL,
	    "overwrite", &cursor);
	ret = session->open_cursor(session, "table:mytable", NULL,
	    "overwrite=true", &cursor);
	ret = session->open_cursor(session, "table:mytable", NULL,
	    "overwrite=1", &cursor);
	/*! [boolean configuration string example] */
	}

	{
	/*! [open a named checkpoint] */
	ret = session->open_cursor(session,
	    "table:mytable", NULL, "checkpoint=midnight", &cursor);
	/*! [open a named checkpoint] */
	}

	{
	/*! [open the default checkpoint] */
	ret = session->open_cursor(session,
	    "table:mytable", NULL, "checkpoint=WiredTigerCheckpoint", &cursor);
	/*! [open the default checkpoint] */
	}

	{
	/*! [Get the cursor's string key] */
	const char *key;	/* Get the cursor's string key. */
	ret = cursor->get_key(cursor, &key);
	/*! [Get the cursor's string key] */
	}

	{
	/*! [Set the cursor's string key] */
				/* Set the cursor's string key. */
	const char *key = "another key";
	cursor->set_key(cursor, key);
	/*! [Set the cursor's string key] */
	}

	{
	/*! [Get the cursor's record number key] */
	uint64_t recno;		/* Get the cursor's record number key. */
	ret = cursor->get_key(cursor, &recno);
	/*! [Get the cursor's record number key] */
	}

	{
	/*! [Set the cursor's record number key] */
	uint64_t recno = 37;	/* Set the cursor's record number key. */
	cursor->set_key(cursor, recno);
	/*! [Set the cursor's record number key] */
	}

	{
	/*! [Get the cursor's composite key] */
			/* Get the cursor's "SiH" format composite key. */
	const char *first;
	int32_t second;
	uint16_t third;
	cursor->get_key(cursor, &first, &second, &third);
	/*! [Get the cursor's composite key] */
	}

	{
	/*! [Set the cursor's composite key] */
			/* Set the cursor's "SiH" format composite key. */
	cursor->set_key(cursor, "first", (int32_t)5, (uint16_t)7);
	/*! [Set the cursor's composite key] */
	}

	{
	/*! [Get the cursor's string value] */
	const char *value;	/* Get the cursor's string value. */
	ret = cursor->get_value(cursor, &value);
	/*! [Get the cursor's string value] */
	}

	{
	/*! [Set the cursor's string value] */
				/* Set the cursor's string value. */
	const char *value = "another value";
	cursor->set_value(cursor, value);
	/*! [Set the cursor's string value] */
	}

	{
	/*! [Get the cursor's raw value] */
	WT_ITEM value;		/* Get the cursor's raw value. */
	ret = cursor->get_value(cursor, &value);
	/*! [Get the cursor's raw value] */
	}

	{
	/*! [Set the cursor's raw value] */
	WT_ITEM value;		/* Set the cursor's raw value. */
	value.data = "another value";
	value.size = strlen("another value");
	cursor->set_value(cursor, &value);
	/*! [Set the cursor's raw value] */
	}

	/*! [Return the next record] */
	ret = cursor->next(cursor);
	/*! [Return the next record] */

	/*! [Return the previous record] */
	ret = cursor->prev(cursor);
	/*! [Return the previous record] */

	/*! [Reset the cursor] */
	ret = cursor->reset(cursor);
	/*! [Reset the cursor] */

	{
	WT_CURSOR *other = NULL;
	/*! [Cursor comparison] */
	int compare;
	ret = cursor->compare(cursor, other, &compare);
	if (compare == 0) {
		/* Cursors reference the same key */
	} else if (compare < 0) {
		/* Cursor key less than other key */
	} else if (compare > 0) {
		/* Cursor key greater than other key */
	}
	/*! [Cursor comparison] */
	}

	{
	/*! [Search for an exact match] */
	const char *key = "some key";
	cursor->set_key(cursor, key);
	ret = cursor->search(cursor);
	/*! [Search for an exact match] */
	}

	cursor_search_near(cursor);

	{
	/*! [Insert a new record or overwrite an existing record] */
	/* Insert a new record or overwrite an existing record. */
	const char *key = "some key", *value = "some value";
	ret = session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor);
	cursor->set_key(cursor, key);
	cursor->set_value(cursor, value);
	ret = cursor->insert(cursor);
	/*! [Insert a new record or overwrite an existing record] */
	}

	{
	/*! [Insert a new record and fail if the record exists] */
	/* Insert a new record and fail if the record exists. */
	const char *key = "some key", *value = "some value";
	ret = session->open_cursor(
	    session, "table:mytable", NULL, "overwrite=false", &cursor);
	cursor->set_key(cursor, key);
	cursor->set_value(cursor, value);
	ret = cursor->insert(cursor);
	/*! [Insert a new record and fail if the record exists] */
	}

	{
	/*! [Insert a new record and assign a record number] */
	/* Insert a new record and assign a record number. */
	uint64_t recno;
	const char *value = "some value";
	ret = session->open_cursor(
	    session, "table:mytable", NULL, "append", &cursor);
	cursor->set_value(cursor, value);
	ret = cursor->insert(cursor);
	if (ret == 0)
		ret = cursor->get_key(cursor, &recno);
	/*! [Insert a new record and assign a record number] */
	}

	{
	/*! [Update an existing record or insert a new record] */
	const char *key = "some key", *value = "some value";
	ret = session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor);
	cursor->set_key(cursor, key);
	cursor->set_value(cursor, value);
	ret = cursor->update(cursor);
	/*! [Update an existing record or insert a new record] */
	}

	{
	/*! [Update an existing record and fail if DNE] */
	const char *key = "some key", *value = "some value";
	ret = session->open_cursor(
	    session, "table:mytable", NULL, "overwrite=false", &cursor);
	cursor->set_key(cursor, key);
	cursor->set_value(cursor, value);
	ret = cursor->update(cursor);
	/*! [Update an existing record and fail if DNE] */
	}

	{
	/*! [Remove a record] */
	const char *key = "some key";
	ret = session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor);
	cursor->set_key(cursor, key);
	ret = cursor->remove(cursor);
	/*! [Remove a record] */
	}

	{
	/*! [Remove a record and fail if DNE] */
	const char *key = "some key";
	ret = session->open_cursor(
	    session, "table:mytable", NULL, "overwrite=false", &cursor);
	cursor->set_key(cursor, key);
	ret = cursor->remove(cursor);
	/*! [Remove a record and fail if DNE] */
	}

	{
	/*! [Display an error] */
	const char *key = "non-existent key";
	cursor->set_key(cursor, key);
	if ((ret = cursor->remove(cursor)) != 0) {
		fprintf(stderr,
		    "cursor.remove: %s\n", wiredtiger_strerror(ret));
		return (ret);
	}
	/*! [Display an error] */
	}

	/*! [Close the cursor] */
	ret = cursor->close(cursor);
	/*! [Close the cursor] */

	return (ret);
}
コード例 #28
0
ファイル: ex_all.c プロジェクト: zhliu03/wiredtiger
int
cursor_ops(WT_SESSION *session)
{
	WT_CURSOR *cursor;
	int ret;

	/*! [Open a cursor] */
	ret = session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor);
	/*! [Open a cursor] */

	{
	WT_CURSOR *duplicate;
	const char *key = "some key";
	/*! [Duplicate a cursor] */
	ret = session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor);
	cursor->set_key(cursor, key);
	ret = cursor->search(cursor);

	/* Duplicate the cursor. */
	ret = session->open_cursor(session, NULL, cursor, NULL, &duplicate);
	/*! [Duplicate a cursor] */
	}

	{
	WT_CURSOR *overwrite_cursor;
	const char *key = "some key", *value = "some value";
	/*! [Reconfigure a cursor] */
	ret = session->open_cursor(
	    session, "table:mytable", NULL, NULL, &cursor);
	cursor->set_key(cursor, key);

	/* Reconfigure the cursor to overwrite the record. */
	ret = session->open_cursor(
	    session, NULL, cursor, "overwrite=true", &overwrite_cursor);
	ret = cursor->close(cursor);

	overwrite_cursor->set_value(overwrite_cursor, value);
	ret = overwrite_cursor->insert(cursor);
	/*! [Reconfigure a cursor] */
	}

	{
	/*! [Get the cursor's string key] */
	const char *key;	/* Get the cursor's string key. */
	ret = cursor->get_key(cursor, &key);
	/*! [Get the cursor's string key] */
	}

	{
	/*! [Get the cursor's record number key] */
	uint64_t recno;		/* Get the cursor's record number key. */
	ret = cursor->get_key(cursor, &recno);
	/*! [Get the cursor's record number key] */
	}

	{
	/*! [Get the cursor's string value] */
	const char *value;	/* Get the cursor's string value. */
	ret = cursor->get_value(cursor, &value);
	/*! [Get the cursor's string value] */
	}

	{
	/*! [Get the cursor's raw value] */
	WT_ITEM value;		/* Get the cursor's raw value. */
	ret = cursor->get_value(cursor, &value);
	/*! [Get the cursor's raw value] */
	}

	{
	/*! [Set the cursor's string key] */
				/* Set the cursor's string key. */
	const char *key = "another key";
	cursor->set_key(cursor, key);
	/*! [Set the cursor's string key] */
	}

	{
	/*! [Set the cursor's record number key] */
	uint64_t recno = 37;	/* Set the cursor's record number key. */
	cursor->set_key(cursor, recno);
	/*! [Set the cursor's record number key] */
	}

	{
	/*! [Set the cursor's string value] */
				/* Set the cursor's string value. */
	const char *value = "another value";
	cursor->set_value(cursor, value);
	/*! [Set the cursor's string value] */
	}
	{
	/*! [Set the cursor's raw value] */
	WT_ITEM value;		/* Set the cursor's raw value. */
	value.data = "another value";
	value.size = strlen("another value");
	cursor->set_value(cursor, &value);
	/*! [Set the cursor's raw value] */
	}

	/*! [Return the next record] */
	ret = cursor->next(cursor);
	/*! [Return the next record] */

	/*! [Return the previous record] */
	ret = cursor->prev(cursor);
	/*! [Return the previous record] */

	/*! [Reset the cursor] */
	ret = cursor->reset(cursor);
	/*! [Reset the cursor] */

	{
	WT_CURSOR *other = NULL;
	/*! [Cursor comparison] */
	int compare;
	ret = cursor->compare(cursor, other, &compare);
	if (compare == 0) {
		/* Cursors reference the same key */
	} else if (compare < 0) {
		/* Cursor key less than other key */
	} else if (compare > 0) {
		/* Cursor key greater than other key */
	}
	/*! [Cursor comparison] */
	}

	{
	/*! [Search for an exact match] */
	const char *key = "some key";
	cursor->set_key(cursor, key);
	ret = cursor->search(cursor);
	/*! [Search for an exact match] */
	}

	cursor_search_near(cursor);

	{
	/*! [Insert a new record] */
	/* Insert a new record. */
	const char *key = "some key", *value = "some value";
	cursor->set_key(cursor, key);
	cursor->set_value(cursor, value);
	ret = cursor->insert(cursor);
	/*! [Insert a new record] */
	}

	{
	const char *key = "some key", *value = "some value";
	/*! [Insert a new record or overwrite an existing record] */
	/* Insert a new record or overwrite an existing record. */
	ret = session->open_cursor(
	    session, "table:mytable", NULL, "overwrite", &cursor);
	cursor->set_key(cursor, key);
	cursor->set_value(cursor, value);
	ret = cursor->insert(cursor);
	/*! [Insert a new record or overwrite an existing record] */
	}

	{
	/*! [Insert a new record and assign a record number] */
	/* Insert a new record and assign a record number. */
	uint64_t recno;
	const char *value = "some value";
	ret = session->open_cursor(
	    session, "table:mytable", NULL, "append", &cursor);
	cursor->set_value(cursor, value);
	ret = cursor->insert(cursor);
	if (ret == 0)
		recno = cursor->get_key(cursor, &recno);
	/*! [Insert a new record and assign a record number] */
	}

	{
	/*! [Update an existing record] */
	const char *key = "some key", *value = "some value";
	cursor->set_key(cursor, key);
	cursor->set_value(cursor, value);
	ret = cursor->update(cursor);
	/*! [Update an existing record] */
	}

	{
	/*! [Remove a record] */
	const char *key = "some key";
	cursor->set_key(cursor, key);
	ret = cursor->remove(cursor);
	/*! [Remove a record] */
	}

	{
	/*! [Display an error] */
	const char *key = "some key";
	cursor->set_key(cursor, key);
	if ((ret = cursor->remove(cursor)) != 0) {
		fprintf(stderr,
		    "cursor.remove: %s\n", wiredtiger_strerror(ret));
		return (ret);
	}
	/*! [Display an error] */
	}

	/*! [Close the cursor] */
	ret = cursor->close(cursor);
	/*! [Close the cursor] */

	return (ret);
}
コード例 #29
0
ファイル: util_write.c プロジェクト: zinuyasha/wiredtiger
int
util_write(WT_SESSION *session, int argc, char *argv[])
{
	WT_CURSOR *cursor;
	uint64_t recno;
	int append, ch, overwrite, rkey, ret;
	const char *uri;
	char config[100];

	append = overwrite = ret = 0;

	while ((ch = util_getopt(argc, argv, "ao")) != EOF)
		switch (ch) {
		case 'a':
			append = 1;
			break;
		case 'o':
			overwrite = 1;
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= util_optind;
	argv += util_optind;

	/*
	 * The remaining arguments are a uri followed by a list of values (if
	 * append is set), or key/value pairs (if append is not set).
	 */
	if (append) {
		if (argc < 2)
			return (usage());
	} else
		if (argc < 3 || ((argc - 1) % 2 != 0))
			return (usage());
	if ((uri =
	    util_name(*argv, "table", UTIL_FILE_OK | UTIL_TABLE_OK)) == NULL)
		return (1);

	/* Open the object. */
	(void)snprintf(config, sizeof(config), "%s,%s",
	    append ? "append=true" : "", overwrite ? "overwrite=true" : "");
	if ((ret = session->open_cursor(
	    session, uri, NULL, config, &cursor)) != 0)
		return (util_err(ret, "%s: session.open", uri));

	/*
	 * A simple search only makes sense if the key format is a string or a
	 * record number, and the value format is a single string.
	 */
	if (strcmp(cursor->key_format, "r") != 0 &&
	    strcmp(cursor->key_format, "S") != 0) {
		fprintf(stderr,
		    "%s: write command only possible when the key format is "
		    "a record number or string\n",
		    progname);
		return (1);
	}
	rkey = strcmp(cursor->key_format, "r") == 0 ? 1 : 0;
	if (strcmp(cursor->value_format, "S") != 0) {
		fprintf(stderr,
		    "%s: write command only possible when the value format is "
		    "a string\n",
		    progname);
		return (1);
	}

	/* Run through the values or key/value pairs. */
	while (*++argv != NULL) {
		if (!append) {
			if (rkey) {
				if (util_str2recno(*argv, &recno))
					return (1);
				cursor->set_key(cursor, recno);
			} else
				cursor->set_key(cursor, *argv);
			++argv;
		}
		cursor->set_value(cursor, *argv);

		if ((ret = cursor->insert(cursor)) != 0)
			return (util_cerr(uri, "search", ret));
	}
		
	return (0);
}
コード例 #30
0
ファイル: bulk.c プロジェクト: wiredtiger/wiredtiger
void
wts_load(void)
{
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_DECL_RET;
	WT_ITEM key, value;
	WT_SESSION *session;
	bool is_bulk;

	conn = g.wts_conn;

	testutil_check(conn->open_session(conn, NULL, NULL, &session));

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

	/*
	 * No bulk load with data-sources.
	 *
	 * No bulk load with custom collators, the order of insertion will not
	 * match the collation order.
	 */
	is_bulk = true;
	if (DATASOURCE("kvsbdb"))
		is_bulk = false;
	if (g.c_reverse)
		is_bulk = false;

	/*
	 * open_cursor can return EBUSY if concurrent with a metadata
	 * operation, retry in that case.
	 */
	while ((ret = session->open_cursor(session, g.uri, NULL,
	    is_bulk ? "bulk,append" : NULL, &cursor)) == EBUSY)
		__wt_yield();
	testutil_check(ret);

	/* Set up the key/value buffers. */
	key_gen_init(&key);
	val_gen_init(&value);

	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 % 1000 == 0)
			track("bulk load", g.key_cnt, NULL);

		key_gen(&key, g.key_cnt);
		val_gen(NULL, &value, g.key_cnt);

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

		/*
		 * We don't want to size the cache to ensure the initial data
		 * set can load in the in-memory case, guaranteeing the load
		 * succeeds probably means future updates are also guaranteed
		 * to succeed, which isn't what we want. If we run out of space
		 * in the initial load, reset the row counter and continue.
		 *
		 * Decrease inserts, they can't be successful if we're at the
		 * cache limit, and increase the delete percentage to get some
		 * extra space once the run starts.
		 */
		if ((ret = cursor->insert(cursor)) != 0) {
			if (ret != WT_CACHE_FULL)
				testutil_die(ret, "cursor.insert");
			g.rows = --g.key_cnt;
			g.c_rows = (uint32_t)g.key_cnt;

			if (g.c_insert_pct > 5)
				g.c_insert_pct = 5;
			if (g.c_delete_pct < 20)
				g.c_delete_pct += 20;
			break;
		}

#ifdef HAVE_BERKELEY_DB
		if (SINGLETHREADED)
			bdb_insert(key.data, key.size, value.data, value.size);
#endif
	}

	testutil_check(cursor->close(cursor));

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

	testutil_check(session->close(session, NULL));

	key_gen_teardown(&key);
	val_gen_teardown(&value);
}