예제 #1
0
파일: kvs_bdb.c 프로젝트: Machyne/mongo
static int
kvs_cursor_update(WT_CURSOR *wtcursor)
{
	CURSOR_SOURCE *cursor;
	DBC *dbc;
	DBT *key, *value;
	WT_EXTENSION_API *wt_api;
	WT_SESSION *session;
	int ret = 0;

	session = wtcursor->session;
	cursor = (CURSOR_SOURCE *)wtcursor;
	wt_api = cursor->wt_api;

	dbc = cursor->dbc;
	key = &cursor->key;
	value = &cursor->value;

	if ((ret = copyin_key(wtcursor)) != 0)
		return (ret);
	copyin_value(wtcursor);

	if ((ret = dbc->put(dbc, key, value, DB_KEYFIRST)) != 0)
		ERET(wt_api,
		    session, WT_ERROR, "DbCursor.put: %s", db_strerror(ret));

	return (0);
}
예제 #2
0
파일: kvs_bdb.c 프로젝트: Machyne/mongo
static int
kvs_cursor_search(WT_CURSOR *wtcursor)
{
	CURSOR_SOURCE *cursor;
	DBC *dbc;
	DBT *key, *value;
	WT_EXTENSION_API *wt_api;
	WT_SESSION *session;
	int ret = 0;

	session = wtcursor->session;
	cursor = (CURSOR_SOURCE *)wtcursor;
	wt_api = cursor->wt_api;

	dbc = cursor->dbc;
	key = &cursor->key;
	value = &cursor->value;

	if ((ret = copyin_key(wtcursor)) != 0)
		return (ret);

	if ((ret = dbc->get(dbc, key, value, DB_SET)) == 0) {
		copyout_key(wtcursor);
		copyout_value(wtcursor);
		return (0);
	}

	if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
		return (WT_NOTFOUND);
	ERET(wt_api, session, WT_ERROR, "DbCursor.get: %s", db_strerror(ret));
}
예제 #3
0
/*
 * kvs_cursor_remove --
 *	WT_CURSOR::remove method.
 */
static int
kvs_cursor_remove(WT_CURSOR *wt_cursor)
{
	CURSOR *cursor;
	WT_SESSION *session;
	int ret;

	cursor = (CURSOR *)wt_cursor;
	session = cursor->session;
	ret = 0;

	/*
	 * WiredTiger's "remove" of a bitfield is really an update with a value
	 * of a single byte of zero.
	 */
	if (cursor->config_bitfield) {
		wt_cursor->value.size = 1;
		wt_cursor->value.data = "\0";
		return (kvs_cursor_update(wt_cursor));
	}

	if ((ret = copyin_key(wt_cursor)) != 0)
		return (ret);
	if ((ret = kvs_del(cursor->data_source->kvs, &cursor->record)) == 0)
		return (0);
	if (ret == KVS_E_KEY_NOT_FOUND)
		return (WT_NOTFOUND);
	ERET(session, WT_ERROR, "kvs_del: %s", kvs_strerror(ret));
}
예제 #4
0
/*
 * kvs_cursor_search --
 *	WT_CURSOR::search method.
 */
static int
kvs_cursor_search(WT_CURSOR *wt_cursor)
{
	int ret;

	if ((ret = copyin_key(wt_cursor)) != 0)
		return (ret);
	if ((ret = kvs_call(wt_cursor, "kvs_get", kvs_get)) != 0)
		return (ret);
	if ((ret = copyout_val(wt_cursor)) != 0)
		return (ret);
	return (0);
}
예제 #5
0
파일: kvs_bdb.c 프로젝트: Machyne/mongo
static int
kvs_cursor_remove(WT_CURSOR *wtcursor)
{
	CURSOR_SOURCE *cursor;
	DBC *dbc;
	DBT *key, *value;
	WT_EXTENSION_API *wt_api;
	WT_SESSION *session;
	int ret = 0;

	session = wtcursor->session;
	cursor = (CURSOR_SOURCE *)wtcursor;
	wt_api = cursor->wt_api;

	dbc = cursor->dbc;
	key = &cursor->key;
	value = &cursor->value;

	/*
	 * WiredTiger's "remove" of a bitfield is really an update with a value
	 * of a single byte of zero.
	 */
	if (cursor->config_bitfield) {
		wtcursor->value.size = 1;
		wtcursor->value.data = "\0";
		return (kvs_cursor_update(wtcursor));
	}

	if ((ret = copyin_key(wtcursor)) != 0)
		return (ret);

	if ((ret = dbc->get(dbc, key, value, DB_SET)) != 0) {
		if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
			return (WT_NOTFOUND);
		ERET(wt_api,
		    session, WT_ERROR, "DbCursor.get: %s", db_strerror(ret));
	}
	if ((ret = dbc->del(dbc, 0)) != 0)
		ERET(wt_api,
		    session, WT_ERROR, "DbCursor.del: %s", db_strerror(ret));

	return (0);
}
예제 #6
0
/*
 * kvs_cursor_insert --
 *	WT_CURSOR::insert method.
 */
static int
kvs_cursor_insert(WT_CURSOR *wt_cursor)
{
	CURSOR *cursor;
	WT_SESSION *session;
	int ret;

	cursor = (CURSOR *)wt_cursor;
	session = cursor->session;
	ret = 0;

	/* Allocate a new record for append operations. */
	if (cursor->config_append && (ret = kvs_recno_alloc(wt_cursor)) != 0)
		return (ret);

	if ((ret = copyin_key(wt_cursor)) != 0)
		return (ret);
	if ((ret = copyin_val(wt_cursor)) != 0)
		return (ret);

	/*
	 * WT_CURSOR::insert with overwrite set (create the record if it does
	 * not exist, update the record if it does exist), maps to kvs_set.
	 *
	 * WT_CURSOR::insert without overwrite set (create the record if it
	 * does not exist, fail if it does exist), maps to kvs_add.
	 */
	if (cursor->config_overwrite) {
		if ((ret = kvs_set(
		    cursor->data_source->kvs, &cursor->record)) != 0)
			ERET(session, WT_ERROR,
			    "kvs_set: %s", kvs_strerror(ret));
	} else
		if ((ret = kvs_add(
		    cursor->data_source->kvs, &cursor->record)) != 0) {
			if (ret == KVS_E_KEY_EXISTS)
				return (WT_DUPLICATE_KEY);
			ERET(session, WT_ERROR,
			    "kvs_add: %s", kvs_strerror(ret));
		}
	return (0);
}
예제 #7
0
/*
 * kvs_cursor_update --
 *	WT_CURSOR::update method.
 */
static int
kvs_cursor_update(WT_CURSOR *wt_cursor)
{
	CURSOR *cursor;
	WT_SESSION *session;
	int ret;

	cursor = (CURSOR *)wt_cursor;
	session = cursor->session;

	if ((ret = copyin_key(wt_cursor)) != 0)
		return (ret);
	if ((ret = copyin_val(wt_cursor)) != 0)
		return (ret);

	/*
	 * WT_CURSOR::update (update the record if it does exist, fail if it
	 * does not exist), maps to kvs_replace.
	 */
	if ((ret = kvs_replace(cursor->data_source->kvs, &cursor->record)) != 0)
		ERET(session, WT_ERROR, "kvs_replace: %s", kvs_strerror(ret));

	return (0);
}
예제 #8
0
파일: kvs_bdb.c 프로젝트: Machyne/mongo
static int
kvs_cursor_insert(WT_CURSOR *wtcursor)
{
	CURSOR_SOURCE *cursor;
	DB *db;
	DBC *dbc;
	DBT *key, *value;
	WT_EXTENSION_API *wt_api;
	WT_SESSION *session;
	int ret = 0;

	session = wtcursor->session;
	cursor = (CURSOR_SOURCE *)wtcursor;
	wt_api = cursor->wt_api;

	dbc = cursor->dbc;
	db = cursor->db;
	key = &cursor->key;
	value = &cursor->value;

	if ((ret = copyin_key(wtcursor)) != 0)
		return (ret);
	copyin_value(wtcursor);

	if (cursor->config_append) {
		/*
		 * Berkeley DB cursors have no operation to append/create a
		 * new record and set the cursor; use the DB handle instead
		 * then set the cursor explicitly.
		 *
		 * When appending, we're allocating and returning a new record
		 * number.
		 */
		if ((ret = db->put(db, NULL, key, value, DB_APPEND)) != 0)
			ERET(wt_api,
			    session, WT_ERROR, "Db.put: %s", db_strerror(ret));
		wtcursor->recno = *(db_recno_t *)key->data;

		if ((ret = dbc->get(dbc, key, value, DB_SET)) != 0)
			ERET(wt_api, session, WT_ERROR,
			    "DbCursor.get: %s", db_strerror(ret));
	} else if (cursor->config_overwrite) {
		if ((ret = dbc->put(dbc, key, value, DB_KEYFIRST)) != 0)
			ERET(wt_api, session, WT_ERROR,
			    "DbCursor.put: %s", db_strerror(ret));
	} else {
		/*
		 * Berkeley DB cursors don't have a no-overwrite flag; use
		 * the DB handle instead then set the cursor explicitly.
		 */
		if ((ret =
		    db->put(db, NULL, key, value, DB_NOOVERWRITE)) != 0) {
			if (ret == DB_KEYEXIST)
				return (WT_DUPLICATE_KEY);
			ERET(wt_api,
			    session, WT_ERROR, "Db.put: %s", db_strerror(ret));
		}
		if ((ret = dbc->get(dbc, key, value, DB_SET)) != 0)
			ERET(wt_api, session, WT_ERROR,
			    "DbCursor.get: %s", db_strerror(ret));
	}

	return (0);
}
예제 #9
0
파일: kvs_bdb.c 프로젝트: Machyne/mongo
static int
kvs_cursor_search_near(WT_CURSOR *wtcursor, int *exact)
{
	CURSOR_SOURCE *cursor;
	DBC *dbc;
	DBT *key, *value;
	WT_EXTENSION_API *wt_api;
	WT_SESSION *session;
	size_t len;
	int ret = 0;

	session = wtcursor->session;
	cursor = (CURSOR_SOURCE *)wtcursor;
	wt_api = cursor->wt_api;

	dbc = cursor->dbc;
	key = &cursor->key;
	value = &cursor->value;

	if ((ret = copyin_key(wtcursor)) != 0)
		return (ret);

retry:	if ((ret = dbc->get(dbc, key, value, DB_SET_RANGE)) == 0) {
		/*
		 * WiredTiger returns the logically adjacent key (which might
		 * be less than, equal to, or greater than the specified key),
		 * Berkeley DB returns a key equal to or greater than the
		 * specified key.  Check for an exact match, otherwise Berkeley
		 * DB must have returned a larger key than the one specified.
		 */
		if (key->size == wtcursor->key.size &&
		    memcmp(key->data, wtcursor->key.data, key->size) == 0)
			*exact = 0;
		else
			*exact = 1;
		copyout_key(wtcursor);
		copyout_value(wtcursor);
		return (0);
	}

	/*
	 * Berkeley DB only returns keys equal to or greater than the specified
	 * key, while WiredTiger returns adjacent keys, that is, if there's a
	 * key smaller than the specified key, it's supposed to be returned.  In
	 * other words, WiredTiger only fails if the store is empty.  Read the
	 * last key in the store, and see if it's less than the specified key,
	 * in which case we have the right key to return.  If it's not less than
	 * the specified key, we're racing with some other thread, throw up our
	 * hands and try again.
	 */
	if ((ret = dbc->get(dbc, key, value, DB_LAST)) == 0) {
		len = key->size < wtcursor->key.size ?
		    key->size : wtcursor->key.size;
		if (memcmp(key->data, wtcursor->key.data, len) < 0) {
			*exact = -1;
			copyout_key(wtcursor);
			copyout_value(wtcursor);
			return (0);
		}
		goto retry;
	}

	if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
		return (WT_NOTFOUND);
	ERET(wt_api, session, WT_ERROR, "DbCursor.get: %s", db_strerror(ret));
}