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