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)); }
/* * 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); }
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)); }