/* * __curfile_search_near -- * WT_CURSOR->search_near method for the btree cursor type. */ static int __curfile_search_near(WT_CURSOR *cursor, int *exact) { WT_CURSOR_BTREE *cbt; WT_DECL_RET; WT_SESSION_IMPL *session; cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_API_CALL(cursor, session, search_near, cbt->btree); WT_CURSOR_NEEDKEY(cursor); ret = __wt_btcur_search_near(cbt, exact); err: API_END(session); return (ret); }
/* * __curbackup_reset -- * WT_CURSOR->reset method for the backup cursor type. */ static int __curbackup_reset(WT_CURSOR *cursor) { WT_CURSOR_BACKUP *cb; WT_DECL_RET; WT_SESSION_IMPL *session; cb = (WT_CURSOR_BACKUP *)cursor; CURSOR_API_CALL(cursor, session, reset, NULL); cb->next = 0; F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET); err: API_END_RET(session, ret); }
/* * __clsm_next -- * WT_CURSOR->next method for the LSM cursor type. */ static int __clsm_next(WT_CURSOR *cursor) { WT_CURSOR_LSM *clsm; WT_CURSOR *c; WT_DECL_RET; WT_SESSION_IMPL *session; u_int i; int cmp; bool check, deleted; clsm = (WT_CURSOR_LSM *)cursor; CURSOR_API_CALL(cursor, session, next, NULL); WT_CURSOR_NOVALUE(cursor); WT_ERR(__clsm_enter(clsm, false, false)); /* If we aren't positioned for a forward scan, get started. */ if (clsm->current == NULL || !F_ISSET(clsm, WT_CLSM_ITERATE_NEXT)) { F_CLR(clsm, WT_CLSM_MULTIPLE); WT_FORALL_CURSORS(clsm, c, i) { if (!F_ISSET(cursor, WT_CURSTD_KEY_SET)) { WT_ERR(c->reset(c)); ret = c->next(c); } else if (c != clsm->current) { c->set_key(c, &cursor->key); if ((ret = c->search_near(c, &cmp)) == 0) { if (cmp < 0) ret = c->next(c); else if (cmp == 0) { if (clsm->current == NULL) clsm->current = c; else F_SET(clsm, WT_CLSM_MULTIPLE); } } else F_CLR(c, WT_CURSTD_KEY_SET); } WT_ERR_NOTFOUND_OK(ret); } F_SET(clsm, WT_CLSM_ITERATE_NEXT); F_CLR(clsm, WT_CLSM_ITERATE_PREV); /* We just positioned *at* the key, now move. */ if (clsm->current != NULL) goto retry; } else {
/* * __curfile_prev -- * WT_CURSOR->prev method for the btree cursor type. */ static int __curfile_prev(WT_CURSOR *cursor) { WT_CURSOR_BTREE *cbt; WT_DECL_RET; WT_SESSION_IMPL *session; cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_API_CALL(cursor, session, prev, cbt->btree); F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET); if ((ret = __wt_btcur_prev(cbt, 0)) == 0) F_SET(cursor, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT); err: API_END_RET(session, ret); }
/* * __curds_search_near -- * WT_CURSOR.search_near method for the data-source cursor type. */ static int __curds_search_near(WT_CURSOR *cursor, int *exact) { WT_DECL_RET; WT_SESSION_IMPL *session; CURSOR_API_CALL(cursor, session, search_near, NULL); WT_ERR(__curds_key_set(cursor)); WT_ERR(cursor->data_source->search_near(cursor->data_source, exact)); __curds_key_get(cursor); __curds_value_get(cursor); err: API_END(session); return (ret); }
/* * __curjoin_reset -- * WT_CURSOR::reset for join cursors. */ static int __curjoin_reset(WT_CURSOR *cursor) { WT_CURSOR_JOIN *cjoin; WT_DECL_RET; WT_SESSION_IMPL *session; cjoin = (WT_CURSOR_JOIN *)cursor; CURSOR_API_CALL(cursor, session, reset, NULL); if (F_ISSET(cjoin, WT_CURJOIN_INITIALIZED)) WT_ERR(__curjoin_entry_iter_reset(cjoin->iter)); err: API_END_RET(session, ret); }
/* * __curfile_reset -- * WT_CURSOR->reset method for the btree cursor type. */ static int __curfile_reset(WT_CURSOR *cursor) { WT_CURSOR_BTREE *cbt; WT_DECL_RET; WT_SESSION_IMPL *session; cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_API_CALL(cursor, session, reset, cbt->btree); ret = __wt_btcur_reset(cbt); F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET); err: API_END_RET(session, ret); }
/* * __curbulk_insert_fix -- * Fixed-length column-store bulk cursor insert. */ static int __curbulk_insert_fix(WT_CURSOR *cursor) { WT_BTREE *btree; WT_CURSOR_BULK *cbulk; WT_DECL_RET; WT_SESSION_IMPL *session; uint64_t recno; cbulk = (WT_CURSOR_BULK *)cursor; btree = cbulk->cbt.btree; /* * Bulk cursor inserts are updates, but don't need auto-commit * transactions because they are single-threaded and not visible * until the bulk cursor is closed. */ CURSOR_API_CALL(cursor, session, insert, btree); WT_STAT_FAST_DATA_INCR(session, cursor_insert_bulk); /* * If the "append" flag was configured, the application doesn't have to * supply a key, else require a key. */ if (F_ISSET(cursor, WT_CURSTD_APPEND)) recno = cbulk->recno + 1; else { WT_CURSOR_CHECKKEY(cursor); if ((recno = cursor->recno) <= cbulk->recno) WT_ERR(__bulk_col_keycmp_err(cbulk)); } WT_CURSOR_CHECKVALUE(cursor); /* * Insert any skipped records as deleted records, update the current * record count. */ for (; recno != cbulk->recno + 1; ++cbulk->recno) WT_ERR(__wt_bulk_insert_fix(session, cbulk, true)); cbulk->recno = recno; /* Insert the current record. */ ret = __wt_bulk_insert_fix(session, cbulk, false); err: API_END_RET(session, ret); }
/* * __curfile_search -- * WT_CURSOR->search method for the btree cursor type. */ static int __curfile_search(WT_CURSOR *cursor) { WT_CURSOR_BTREE *cbt; WT_DECL_RET; WT_SESSION_IMPL *session; cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_API_CALL(cursor, session, search, cbt->btree); WT_CURSOR_NEEDKEY(cursor); WT_CURSOR_NOVALUE(cursor); WT_BTREE_CURSOR_SAVE_AND_RESTORE(cursor, __wt_btcur_search(cbt), ret); err: API_END_RET(session, ret); }
/* * __curjoin_close -- * WT_CURSOR::close for join cursors. */ static int __curjoin_close(WT_CURSOR *cursor) { WT_CURSOR_JOIN *cjoin; WT_CURSOR_JOIN_ENDPOINT *end; WT_CURSOR_JOIN_ENTRY *entry; WT_DECL_RET; WT_SESSION_IMPL *session; u_int i; cjoin = (WT_CURSOR_JOIN *)cursor; CURSOR_API_CALL(cursor, session, close, NULL); __wt_schema_release_table(session, cjoin->table); /* These are owned by the table */ cursor->internal_uri = NULL; cursor->key_format = NULL; if (cjoin->projection != NULL) { __wt_free(session, cjoin->projection); __wt_free(session, cursor->value_format); } for (entry = cjoin->entries, i = 0; i < cjoin->entries_next; entry++, i++) { if (entry->main != NULL) WT_TRET(entry->main->close(entry->main)); if (F_ISSET(entry, WT_CURJOIN_ENTRY_OWN_BLOOM)) WT_TRET(__wt_bloom_close(entry->bloom)); for (end = &entry->ends[0]; end < &entry->ends[entry->ends_next]; end++) { F_CLR(end->cursor, WT_CURSTD_JOINED); if (F_ISSET(end, WT_CURJOIN_END_OWN_KEY)) __wt_free(session, end->key.data); } __wt_free(session, entry->ends); } if (cjoin->iter != NULL) WT_TRET(__curjoin_entry_iter_close(cjoin->iter)); __wt_free(session, cjoin->entries); WT_TRET(__wt_cursor_close(cursor)); err: API_END_RET(session, ret); }
/* * __curjoin_next -- * WT_CURSOR::next for join cursors. */ static int __curjoin_next(WT_CURSOR *cursor) { WT_CURSOR_JOIN *cjoin; WT_DECL_RET; WT_SESSION_IMPL *session; bool skip_left; u_int i; cjoin = (WT_CURSOR_JOIN *)cursor; CURSOR_API_CALL(cursor, session, next, NULL); if (F_ISSET(cjoin, WT_CURJOIN_ERROR)) WT_ERR_MSG(session, WT_ERROR, "join cursor encountered previous error"); if (!F_ISSET(cjoin, WT_CURJOIN_INITIALIZED)) WT_ERR(__curjoin_init_iter(session, cjoin)); nextkey: if ((ret = __curjoin_entry_iter_next(cjoin->iter, &cursor->key, &cursor->recno)) == 0) { F_SET(cursor, WT_CURSTD_KEY_EXT); /* * We may have already established membership for the * 'left' case for the first entry, since we're * using that in our iteration. */ skip_left = F_ISSET(cjoin, WT_CURJOIN_SKIP_FIRST_LEFT); for (i = 0; i < cjoin->entries_next; i++) { ret = __curjoin_entry_member(session, cjoin, &cjoin->entries[i], skip_left); if (ret == WT_NOTFOUND) goto nextkey; skip_left = false; WT_ERR(ret); } } if (0) { err: F_SET(cjoin, WT_CURJOIN_ERROR); } API_END_RET(session, ret); }
/* * __curmetadata_close -- * WT_CURSOR->close method for the metadata cursor type. */ static int __curmetadata_close(WT_CURSOR *cursor) { WT_CURSOR *file_cursor; WT_CURSOR_METADATA *mdc; WT_DECL_RET; WT_SESSION_IMPL *session; mdc = (WT_CURSOR_METADATA *)cursor; file_cursor = mdc->file_cursor; CURSOR_API_CALL(cursor, session, close, ((WT_CURSOR_BTREE *)file_cursor)->btree); ret = file_cursor->close(file_cursor); WT_TRET(__wt_cursor_close(cursor)); err: API_END_RET(session, ret); }
/* * __curfile_next -- * WT_CURSOR->next method for the btree cursor type. */ static int __curfile_next(WT_CURSOR *cursor) { WT_CURSOR_BTREE *cbt; WT_DECL_RET; WT_SESSION_IMPL *session; cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_API_CALL(cursor, session, next, cbt->btree); WT_ERR(__wt_btcur_next(cbt, false)); /* Next maintains a position, key and value. */ WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT && F_MASK(cursor, WT_CURSTD_VALUE_SET) == WT_CURSTD_VALUE_INT); err: API_END_RET(session, ret); }
/* * __curfile_reset -- * WT_CURSOR->reset method for the btree cursor type. */ static int __curfile_reset(WT_CURSOR *cursor) { WT_CURSOR_BTREE *cbt; WT_DECL_RET; WT_SESSION_IMPL *session; cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_API_CALL(cursor, session, reset, cbt->btree); ret = __wt_btcur_reset(cbt); /* Reset maintains no position, key or value. */ WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_KEY_SET) == 0 && F_MASK(cursor, WT_CURSTD_VALUE_SET) == 0); err: API_END_RET(session, ret); }
/* * __curdump_set_key -- * WT_CURSOR->set_key for dump cursors. */ static void __curdump_set_key(WT_CURSOR *cursor, ...) { WT_CURSOR_DUMP *cdump; WT_CURSOR *child; WT_DECL_RET; WT_SESSION_IMPL *session; uint64_t recno; va_list ap; const char *p; cdump = (WT_CURSOR_DUMP *)cursor; child = cdump->child; CURSOR_API_CALL(cursor, session, set_key, NULL); va_start(ap, cursor); if (F_ISSET(cursor, WT_CURSTD_RAW)) p = va_arg(ap, WT_ITEM *)->data; else
/* * __curfile_close -- * WT_CURSOR->close method for the btree cursor type. */ static int __curfile_close(WT_CURSOR *cursor) { WT_CURSOR_BTREE *cbt; WT_DECL_RET; WT_SESSION_IMPL *session; cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_API_CALL(cursor, session, close, cbt->btree); WT_TRET(__wt_btcur_close(cbt)); if (session->btree != NULL) WT_TRET(__wt_session_release_btree(session)); /* The URI is owned by the btree handle. */ cursor->uri = NULL; WT_TRET(__wt_cursor_close(cursor)); API_END(session); return (ret); }
/* * __curbulk_insert -- * WT_CURSOR->insert for the bulk cursor type. */ static int __curbulk_insert(WT_CURSOR *cursor) { WT_BTREE *btree; WT_CURSOR_BULK *cbulk; WT_SESSION_IMPL *session; int ret; cbulk = (WT_CURSOR_BULK *)cursor; btree = cbulk->cbt.btree; CURSOR_API_CALL(cursor, session, insert, btree); if (btree->type == BTREE_ROW) WT_CURSOR_NEEDKEY(cursor); WT_CURSOR_NEEDVALUE(cursor); WT_ERR(__wt_bulk_insert(cbulk)); err: API_END(session); return (ret); }
/* * __curbulk_insert_row -- * Row-store bulk cursor insert, with key-sort checks. */ static int __curbulk_insert_row(WT_CURSOR *cursor) { WT_BTREE *btree; WT_CURSOR_BULK *cbulk; WT_DECL_RET; WT_SESSION_IMPL *session; int cmp; cbulk = (WT_CURSOR_BULK *)cursor; btree = cbulk->cbt.btree; /* * Bulk cursor inserts are updates, but don't need auto-commit * transactions because they are single-threaded and not visible * until the bulk cursor is closed. */ CURSOR_API_CALL(cursor, session, insert, btree); WT_STAT_FAST_DATA_INCR(session, cursor_insert_bulk); WT_CURSOR_CHECKKEY(cursor); WT_CURSOR_CHECKVALUE(cursor); /* * If this isn't the first key inserted, compare it against the last key * to ensure the application doesn't accidentally corrupt the table. */ if (!cbulk->first_insert) { WT_ERR(__wt_compare(session, btree->collator, &cursor->key, &cbulk->last, &cmp)); if (cmp <= 0) WT_ERR(__bulk_row_keycmp_err(cbulk)); } else cbulk->first_insert = false; /* Save a copy of the key for the next comparison. */ WT_ERR(__wt_buf_set(session, &cbulk->last, cursor->key.data, cursor->key.size)); ret = __wt_bulk_insert_row(session, cbulk); err: API_END_RET(session, ret); }
/* * __curlog_close -- * WT_CURSOR.close method for the log cursor type. */ static int __curlog_close(WT_CURSOR *cursor) { WT_CURSOR_LOG *cl; WT_DECL_RET; WT_SESSION_IMPL *session; CURSOR_API_CALL(cursor, session, close, NULL); cl = (WT_CURSOR_LOG *)cursor; WT_ERR(__curlog_reset(cursor)); __wt_free(session, cl->cur_lsn); __wt_free(session, cl->next_lsn); __wt_scr_free(&cl->logrec); __wt_scr_free(&cl->opkey); __wt_scr_free(&cl->opvalue); WT_ERR(__wt_cursor_close(cursor)); err: API_END_RET(session, ret); }
/* * __curds_reset -- * WT_CURSOR.reset method for the data-source cursor type. */ static int __curds_reset(WT_CURSOR *cursor) { WT_CURSOR *source; WT_DECL_RET; WT_SESSION_IMPL *session; source = ((WT_CURSOR_DATA_SOURCE *)cursor)->source; CURSOR_API_CALL(cursor, session, reset, NULL); WT_STAT_CONN_INCR(session, cursor_reset); WT_STAT_DATA_INCR(session, cursor_reset); WT_ERR(source->reset(source)); F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET); err: API_END_RET(session, ret); }
/* * __curfile_search_near -- * WT_CURSOR->search_near method for the btree cursor type. */ static int __curfile_search_near(WT_CURSOR *cursor, int *exact) { WT_CURSOR_BTREE *cbt; WT_DECL_RET; WT_SESSION_IMPL *session; cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_API_CALL(cursor, session, search_near, cbt->btree); WT_ERR(__cursor_checkkey(cursor)); WT_ERR(__wt_btcur_search_near(cbt, exact)); /* Search-near maintains a position, key and value. */ WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT && F_MASK(cursor, WT_CURSTD_VALUE_SET) == WT_CURSTD_VALUE_INT); err: API_END_RET(session, ret); }
/* * __curmetadata_reset -- * WT_CURSOR->reset method for the metadata cursor type. */ static int __curmetadata_reset(WT_CURSOR *cursor) { WT_CURSOR *file_cursor; WT_CURSOR_METADATA *mdc; WT_DECL_RET; WT_SESSION_IMPL *session; mdc = (WT_CURSOR_METADATA *)cursor; file_cursor = mdc->file_cursor; CURSOR_API_CALL(cursor, session, reset, ((WT_CURSOR_BTREE *)file_cursor)->btree); if (F_ISSET(mdc, WT_MDC_POSITIONED) && !F_ISSET(mdc, WT_MDC_ONMETADATA)) ret = file_cursor->reset(file_cursor); F_CLR(mdc, WT_MDC_POSITIONED | WT_MDC_ONMETADATA); F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET); err: API_END_RET(session, ret); }
/* * __curds_compare -- * WT_CURSOR.compare method for the data-source cursor type. */ static int __curds_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp) { WT_COLLATOR *collator; WT_DECL_RET; WT_SESSION_IMPL *session; CURSOR_API_CALL(a, session, compare, NULL); /* * Confirm both cursors refer to the same source and have keys, then * compare them. */ if (strcmp(a->internal_uri, b->internal_uri) != 0) WT_ERR_MSG(session, EINVAL, "Cursors must reference the same object"); WT_ERR(__cursor_needkey(a)); WT_ERR(__cursor_needkey(b)); if (WT_CURSOR_RECNO(a)) { if (a->recno < b->recno) *cmpp = -1; else if (a->recno == b->recno) *cmpp = 0; else *cmpp = 1; } else { /* * The assumption is data-sources don't provide WiredTiger with * WT_CURSOR.compare methods, instead, we'll copy the key/value * out of the underlying data-source cursor and any comparison * to be done can be done at this level. */ collator = ((WT_CURSOR_DATA_SOURCE *)a)->collator; WT_ERR(__wt_compare( session, collator, &a->key, &b->key, cmpp)); } err: API_END_RET(session, ret); }
/* * __curbackup_close -- * WT_CURSOR->close method for the backup cursor type. */ static int __curbackup_close(WT_CURSOR *cursor) { WT_CURSOR_BACKUP *cb; WT_DECL_RET; WT_SESSION_IMPL *session; int tret; cb = (WT_CURSOR_BACKUP *)cursor; CURSOR_API_CALL(cursor, session, close, NULL); WT_TRET(__backup_cleanup_handles(session, cb)); WT_TRET(__wt_cursor_close(cursor)); session->bkp_cursor = NULL; WT_WITH_SCHEMA_LOCK(session, tret = __backup_stop(session)); /* Stop the backup. */ WT_TRET(tret); err: API_END_RET(session, ret); }
/* * __curjoin_get_key -- * WT_CURSOR->get_key for join cursors. */ static int __curjoin_get_key(WT_CURSOR *cursor, ...) { WT_CURSOR_JOIN *cjoin; WT_DECL_RET; WT_SESSION_IMPL *session; va_list ap; cjoin = (WT_CURSOR_JOIN *)cursor; va_start(ap, cursor); CURSOR_API_CALL(cursor, session, get_key, NULL); if (!F_ISSET(cjoin, WT_CURJOIN_INITIALIZED) || !__curjoin_entry_iter_ready(cjoin->iter)) WT_ERR_MSG(session, EINVAL, "join cursor must be advanced with next()"); WT_ERR(__wt_cursor_get_keyv(cursor, cursor->flags, ap)); err: va_end(ap); API_END_RET(session, ret); }
/* * __curds_prev -- * WT_CURSOR.prev method for the data-source cursor type. */ static int __curds_prev(WT_CURSOR *cursor) { WT_CURSOR *source; WT_DECL_RET; WT_SESSION_IMPL *session; source = ((WT_CURSOR_DATA_SOURCE *)cursor)->source; CURSOR_API_CALL(cursor, session, prev, NULL); WT_STAT_CONN_INCR(session, cursor_prev); WT_STAT_DATA_INCR(session, cursor_prev); WT_ERR(__curds_txn_enter(session, false)); F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET); ret = __curds_cursor_resolve(cursor, source->prev(source)); err: __curds_txn_leave(session); API_END_RET(session, ret); }
/* * __curlog_compare -- * WT_CURSOR.compare method for the log cursor type. */ static int __curlog_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp) { WT_CURSOR_LOG *acl, *bcl; WT_DECL_RET; WT_SESSION_IMPL *session; CURSOR_API_CALL(a, session, compare, NULL); acl = (WT_CURSOR_LOG *)a; bcl = (WT_CURSOR_LOG *)b; WT_ASSERT(session, cmpp != NULL); *cmpp = LOG_CMP(acl->cur_lsn, bcl->cur_lsn); /* * If both are on the same LSN, compare step counter. */ if (*cmpp == 0) *cmpp = (acl->step_count != bcl->step_count ? (acl->step_count < bcl->step_count ? -1 : 1) : 0); err: API_END_RET(session, ret); }
/* * __curbulk_close -- * WT_CURSOR->close for the bulk cursor type. */ static int __curbulk_close(WT_CURSOR *cursor) { WT_BTREE *btree; WT_CURSOR_BULK *cbulk; WT_SESSION_IMPL *session; int ret; cbulk = (WT_CURSOR_BULK *)cursor; btree = cbulk->cbt.btree; CURSOR_API_CALL(cursor, session, close, btree); WT_TRET(__wt_bulk_end(cbulk)); if (session->btree != NULL) WT_TRET(__wt_session_release_btree(session)); /* The URI is owned by the btree handle. */ cursor->uri = NULL; WT_TRET(__wt_cursor_close(cursor)); API_END(session); return (ret); }
/* * __curbackup_next -- * WT_CURSOR->next method for the backup cursor type. */ static int __curbackup_next(WT_CURSOR *cursor) { WT_CURSOR_BACKUP *cb; WT_DECL_RET; WT_SESSION_IMPL *session; cb = (WT_CURSOR_BACKUP *)cursor; CURSOR_API_CALL(cursor, session, next, NULL); if (cb->list == NULL || cb->list[cb->next].name == NULL) { F_CLR(cursor, WT_CURSTD_KEY_SET); WT_ERR(WT_NOTFOUND); } cb->iface.key.data = cb->list[cb->next].name; cb->iface.key.size = strlen(cb->list[cb->next].name) + 1; ++cb->next; F_SET(cursor, WT_CURSTD_KEY_INT); err: API_END_RET(session, ret); }
/* * __curds_search -- * WT_CURSOR.search method for the data-source cursor type. */ static int __curds_search(WT_CURSOR *cursor) { WT_CURSOR *source; WT_DECL_RET; WT_SESSION_IMPL *session; source = ((WT_CURSOR_DATA_SOURCE *)cursor)->source; CURSOR_API_CALL(cursor, session, search, NULL); WT_STAT_CONN_INCR(session, cursor_search); WT_STAT_DATA_INCR(session, cursor_search); WT_ERR(__curds_txn_enter(session, false)); WT_ERR(__curds_key_set(cursor)); ret = __curds_cursor_resolve(cursor, source->search(source)); err: __curds_txn_leave(session); API_END_RET(session, ret); }