Beispiel #1
0
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));
}
Beispiel #2
0
/*
 * kvs_cursor_prev --
 *	WT_CURSOR::prev method.
 */
static int
kvs_cursor_prev(WT_CURSOR *wt_cursor)
{
	int ret;

	if ((ret = copy_key(wt_cursor)) != 0)
		return (ret);
	if ((ret = kvs_call(wt_cursor, "kvs_prev", kvs_prev)) != 0)
		return (ret);
	if ((ret = copyout_key(wt_cursor)) != 0)
		return (ret);
	if ((ret = copyout_val(wt_cursor)) != 0)
		return (ret);
	return (0);
}
Beispiel #3
0
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));
}