summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/cursor/cur_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/src/cursor/cur_file.c')
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_file.c1249
1 files changed, 605 insertions, 644 deletions
diff --git a/src/third_party/wiredtiger/src/cursor/cur_file.c b/src/third_party/wiredtiger/src/cursor/cur_file.c
index 73225c9613a..e73820baad7 100644
--- a/src/third_party/wiredtiger/src/cursor/cur_file.c
+++ b/src/third_party/wiredtiger/src/cursor/cur_file.c
@@ -9,833 +9,794 @@
#include "wt_internal.h"
/*
- * Define functions that increment histogram statistics for cursor read and
- * write operations latency.
+ * Define functions that increment histogram statistics for cursor read and write operations
+ * latency.
*/
WT_STAT_USECS_HIST_INCR_FUNC(opread, perf_hist_opread_latency, 100)
WT_STAT_USECS_HIST_INCR_FUNC(opwrite, perf_hist_opwrite_latency, 100)
/*
* __curfile_compare --
- * WT_CURSOR->compare method for the btree cursor type.
+ * WT_CURSOR->compare method for the btree cursor type.
*/
static int
__curfile_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp)
{
- WT_CURSOR_BTREE *cbt;
- WT_DECL_RET;
- WT_SESSION_IMPL *session;
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
- cbt = (WT_CURSOR_BTREE *)a;
- CURSOR_API_CALL(a, session, compare, cbt->btree);
+ cbt = (WT_CURSOR_BTREE *)a;
+ CURSOR_API_CALL(a, session, compare, cbt->btree);
- /*
- * Check both cursors are a "file:" type then call the underlying
- * function, it can handle cursors pointing to different objects.
- */
- if (!WT_PREFIX_MATCH(a->internal_uri, "file:") ||
- !WT_PREFIX_MATCH(b->internal_uri, "file:"))
- WT_ERR_MSG(session, EINVAL,
- "Cursors must reference the same object");
+ /*
+ * Check both cursors are a "file:" type then call the underlying function, it can handle
+ * cursors pointing to different objects.
+ */
+ if (!WT_PREFIX_MATCH(a->internal_uri, "file:") || !WT_PREFIX_MATCH(b->internal_uri, "file:"))
+ WT_ERR_MSG(session, EINVAL, "Cursors must reference the same object");
- WT_ERR(__cursor_checkkey(a));
- WT_ERR(__cursor_checkkey(b));
+ WT_ERR(__cursor_checkkey(a));
+ WT_ERR(__cursor_checkkey(b));
- ret = __wt_btcur_compare(
- (WT_CURSOR_BTREE *)a, (WT_CURSOR_BTREE *)b, cmpp);
+ ret = __wt_btcur_compare((WT_CURSOR_BTREE *)a, (WT_CURSOR_BTREE *)b, cmpp);
-err: API_END_RET(session, ret);
+err:
+ API_END_RET(session, ret);
}
/*
* __curfile_equals --
- * WT_CURSOR->equals method for the btree cursor type.
+ * WT_CURSOR->equals method for the btree cursor type.
*/
static int
__curfile_equals(WT_CURSOR *a, WT_CURSOR *b, int *equalp)
{
- WT_CURSOR_BTREE *cbt;
- WT_DECL_RET;
- WT_SESSION_IMPL *session;
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
- cbt = (WT_CURSOR_BTREE *)a;
- CURSOR_API_CALL(a, session, equals, cbt->btree);
+ cbt = (WT_CURSOR_BTREE *)a;
+ CURSOR_API_CALL(a, session, equals, cbt->btree);
- /*
- * Check both cursors are a "file:" type then call the underlying
- * function, it can handle cursors pointing to different objects.
- */
- if (!WT_PREFIX_MATCH(a->internal_uri, "file:") ||
- !WT_PREFIX_MATCH(b->internal_uri, "file:"))
- WT_ERR_MSG(session, EINVAL,
- "Cursors must reference the same object");
+ /*
+ * Check both cursors are a "file:" type then call the underlying function, it can handle
+ * cursors pointing to different objects.
+ */
+ if (!WT_PREFIX_MATCH(a->internal_uri, "file:") || !WT_PREFIX_MATCH(b->internal_uri, "file:"))
+ WT_ERR_MSG(session, EINVAL, "Cursors must reference the same object");
- WT_ERR(__cursor_checkkey(a));
- WT_ERR(__cursor_checkkey(b));
+ WT_ERR(__cursor_checkkey(a));
+ WT_ERR(__cursor_checkkey(b));
- ret = __wt_btcur_equals(
- (WT_CURSOR_BTREE *)a, (WT_CURSOR_BTREE *)b, equalp);
+ ret = __wt_btcur_equals((WT_CURSOR_BTREE *)a, (WT_CURSOR_BTREE *)b, equalp);
-err: API_END_RET(session, ret);
+err:
+ API_END_RET(session, ret);
}
/*
* __curfile_next --
- * WT_CURSOR->next method for the btree cursor type.
+ * 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;
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
- cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL(cursor, session, next, cbt->btree);
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ CURSOR_API_CALL(cursor, session, next, cbt->btree);
- WT_ERR(__wt_btcur_next(cbt, false));
+ WT_ERR(__wt_btcur_next(cbt, false));
- /* Next maintains a position, key and value. */
- WT_ASSERT(session,
- F_ISSET(cbt, WT_CBT_ACTIVE) &&
- F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT &&
- F_MASK(cursor, WT_CURSTD_VALUE_SET) == WT_CURSTD_VALUE_INT);
+ /* Next maintains a position, key and value. */
+ WT_ASSERT(session, F_ISSET(cbt, WT_CBT_ACTIVE) &&
+ 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);
+err:
+ API_END_RET(session, ret);
}
/*
* __wt_curfile_next_random --
- * WT_CURSOR->next method for the btree cursor type when configured with
- * next_random. This is exported because it is called directly within LSM.
+ * WT_CURSOR->next method for the btree cursor type when configured with next_random. This is
+ * exported because it is called directly within LSM.
*/
int
__wt_curfile_next_random(WT_CURSOR *cursor)
{
- WT_CURSOR_BTREE *cbt;
- WT_DECL_RET;
- WT_SESSION_IMPL *session;
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
- cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL(cursor, session, next, cbt->btree);
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ CURSOR_API_CALL(cursor, session, next, cbt->btree);
- WT_ERR(__wt_btcur_next_random(cbt));
+ WT_ERR(__wt_btcur_next_random(cbt));
- /* Next-random maintains a position, key and value. */
- WT_ASSERT(session,
- F_ISSET(cbt, WT_CBT_ACTIVE) &&
- F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT &&
- F_MASK(cursor, WT_CURSTD_VALUE_SET) == WT_CURSTD_VALUE_INT);
+ /* Next-random maintains a position, key and value. */
+ WT_ASSERT(session, F_ISSET(cbt, WT_CBT_ACTIVE) &&
+ 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);
+err:
+ API_END_RET(session, ret);
}
/*
* __curfile_prev --
- * WT_CURSOR->prev method for the btree cursor type.
+ * 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;
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
- cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL(cursor, session, prev, cbt->btree);
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ CURSOR_API_CALL(cursor, session, prev, cbt->btree);
- WT_ERR(__wt_btcur_prev(cbt, false));
+ WT_ERR(__wt_btcur_prev(cbt, false));
- /* Prev maintains a position, key and value. */
- WT_ASSERT(session,
- F_ISSET(cbt, WT_CBT_ACTIVE) &&
- F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT &&
- F_MASK(cursor, WT_CURSTD_VALUE_SET) == WT_CURSTD_VALUE_INT);
+ /* Prev maintains a position, key and value. */
+ WT_ASSERT(session, F_ISSET(cbt, WT_CBT_ACTIVE) &&
+ 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);
+err:
+ API_END_RET(session, ret);
}
/*
* __curfile_reset --
- * WT_CURSOR->reset method for the btree cursor type.
+ * 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;
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
- cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL_PREPARE_ALLOWED(cursor, session, reset, cbt->btree);
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ CURSOR_API_CALL_PREPARE_ALLOWED(cursor, session, reset, cbt->btree);
- ret = __wt_btcur_reset(cbt);
+ ret = __wt_btcur_reset(cbt);
- /* Reset maintains no position, key or value. */
- WT_ASSERT(session,
- !F_ISSET(cbt, WT_CBT_ACTIVE) &&
- F_MASK(cursor, WT_CURSTD_KEY_SET) == 0 &&
- F_MASK(cursor, WT_CURSTD_VALUE_SET) == 0);
+ /* Reset maintains no position, key or value. */
+ WT_ASSERT(session, !F_ISSET(cbt, WT_CBT_ACTIVE) && F_MASK(cursor, WT_CURSTD_KEY_SET) == 0 &&
+ F_MASK(cursor, WT_CURSTD_VALUE_SET) == 0);
-err: API_END_RET(session, ret);
+err:
+ API_END_RET(session, ret);
}
/*
* __curfile_search --
- * WT_CURSOR->search method for the btree cursor type.
+ * 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;
- uint64_t time_start, time_stop;
-
- cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL(cursor, session, search, cbt->btree);
- WT_ERR(__cursor_checkkey(cursor));
-
- time_start = __wt_clock(session);
- WT_ERR(__wt_btcur_search(cbt));
- time_stop = __wt_clock(session);
- __wt_stat_usecs_hist_incr_opread(session,
- WT_CLOCKDIFF_US(time_stop, time_start));
-
- /* Search maintains a position, key and value. */
- WT_ASSERT(session,
- F_ISSET(cbt, WT_CBT_ACTIVE) &&
- 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);
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+ uint64_t time_start, time_stop;
+
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ CURSOR_API_CALL(cursor, session, search, cbt->btree);
+ WT_ERR(__cursor_checkkey(cursor));
+
+ time_start = __wt_clock(session);
+ WT_ERR(__wt_btcur_search(cbt));
+ time_stop = __wt_clock(session);
+ __wt_stat_usecs_hist_incr_opread(session, WT_CLOCKDIFF_US(time_stop, time_start));
+
+ /* Search maintains a position, key and value. */
+ WT_ASSERT(session, F_ISSET(cbt, WT_CBT_ACTIVE) &&
+ 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_search_near --
- * WT_CURSOR->search_near method for the btree cursor type.
+ * 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;
- uint64_t time_start, time_stop;
-
- cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL(cursor, session, search_near, cbt->btree);
- WT_ERR(__cursor_checkkey(cursor));
-
- time_start = __wt_clock(session);
- WT_ERR(__wt_btcur_search_near(cbt, exact));
- time_stop = __wt_clock(session);
- __wt_stat_usecs_hist_incr_opread(session,
- WT_CLOCKDIFF_US(time_stop, time_start));
-
- /* Search-near maintains a position, key and value. */
- WT_ASSERT(session,
- F_ISSET(cbt, WT_CBT_ACTIVE) &&
- 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);
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+ uint64_t time_start, time_stop;
+
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ CURSOR_API_CALL(cursor, session, search_near, cbt->btree);
+ WT_ERR(__cursor_checkkey(cursor));
+
+ time_start = __wt_clock(session);
+ WT_ERR(__wt_btcur_search_near(cbt, exact));
+ time_stop = __wt_clock(session);
+ __wt_stat_usecs_hist_incr_opread(session, WT_CLOCKDIFF_US(time_stop, time_start));
+
+ /* Search-near maintains a position, key and value. */
+ WT_ASSERT(session, F_ISSET(cbt, WT_CBT_ACTIVE) &&
+ 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_insert --
- * WT_CURSOR->insert method for the btree cursor type.
+ * WT_CURSOR->insert method for the btree cursor type.
*/
static int
__curfile_insert(WT_CURSOR *cursor)
{
- WT_CURSOR_BTREE *cbt;
- WT_DECL_RET;
- WT_SESSION_IMPL *session;
- uint64_t time_start, time_stop;
-
- cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_UPDATE_API_CALL_BTREE(cursor, session, insert, cbt->btree);
-
- if (!F_ISSET(cursor, WT_CURSTD_APPEND))
- WT_ERR(__cursor_checkkey(cursor));
- WT_ERR(__cursor_checkvalue(cursor));
-
- time_start = __wt_clock(session);
- WT_ERR(__wt_btcur_insert(cbt));
- time_stop = __wt_clock(session);
- __wt_stat_usecs_hist_incr_opwrite(session,
- WT_CLOCKDIFF_US(time_stop, time_start));
-
- /*
- * Insert maintains no position, key or value (except for column-store
- * appends, where we are returning a key).
- */
- WT_ASSERT(session,
- !F_ISSET(cbt, WT_CBT_ACTIVE) &&
- ((F_ISSET(cursor, WT_CURSTD_APPEND) &&
- F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_EXT) ||
- (!F_ISSET(cursor, WT_CURSTD_APPEND) &&
- F_MASK(cursor, WT_CURSTD_KEY_SET) == 0)));
- WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_VALUE_SET) == 0);
-
-err: CURSOR_UPDATE_API_END(session, ret);
- return (ret);
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+ uint64_t time_start, time_stop;
+
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ CURSOR_UPDATE_API_CALL_BTREE(cursor, session, insert, cbt->btree);
+
+ if (!F_ISSET(cursor, WT_CURSTD_APPEND))
+ WT_ERR(__cursor_checkkey(cursor));
+ WT_ERR(__cursor_checkvalue(cursor));
+
+ time_start = __wt_clock(session);
+ WT_ERR(__wt_btcur_insert(cbt));
+ time_stop = __wt_clock(session);
+ __wt_stat_usecs_hist_incr_opwrite(session, WT_CLOCKDIFF_US(time_stop, time_start));
+
+ /*
+ * Insert maintains no position, key or value (except for column-store appends, where we are
+ * returning a key).
+ */
+ WT_ASSERT(session, !F_ISSET(cbt, WT_CBT_ACTIVE) &&
+ ((F_ISSET(cursor, WT_CURSTD_APPEND) &&
+ F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_EXT) ||
+ (!F_ISSET(cursor, WT_CURSTD_APPEND) && F_MASK(cursor, WT_CURSTD_KEY_SET) == 0)));
+ WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_VALUE_SET) == 0);
+
+err:
+ CURSOR_UPDATE_API_END(session, ret);
+ return (ret);
}
/*
* __wt_curfile_insert_check --
- * WT_CURSOR->insert_check method for the btree cursor type.
+ * WT_CURSOR->insert_check method for the btree cursor type.
*/
int
__wt_curfile_insert_check(WT_CURSOR *cursor)
{
- WT_CURSOR_BTREE *cbt;
- WT_DECL_RET;
- WT_SESSION_IMPL *session;
- int tret;
-
- cbt = (WT_CURSOR_BTREE *)cursor;
- tret = 0;
- CURSOR_UPDATE_API_CALL_BTREE(cursor, session, update, cbt->btree);
- WT_ERR(__cursor_checkkey(cursor));
-
- tret = __wt_btcur_insert_check(cbt);
-
- /*
- * Detecting a conflict should not cause transaction error.
- */
-err: CURSOR_UPDATE_API_END(session, ret);
- WT_TRET(tret);
- return (ret);
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+ int tret;
+
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ tret = 0;
+ CURSOR_UPDATE_API_CALL_BTREE(cursor, session, update, cbt->btree);
+ WT_ERR(__cursor_checkkey(cursor));
+
+ tret = __wt_btcur_insert_check(cbt);
+
+/*
+ * Detecting a conflict should not cause transaction error.
+ */
+err:
+ CURSOR_UPDATE_API_END(session, ret);
+ WT_TRET(tret);
+ return (ret);
}
/*
* __curfile_modify --
- * WT_CURSOR->modify method for the btree cursor type.
+ * WT_CURSOR->modify method for the btree cursor type.
*/
static int
__curfile_modify(WT_CURSOR *cursor, WT_MODIFY *entries, int nentries)
{
- WT_CURSOR_BTREE *cbt;
- WT_DECL_RET;
- WT_SESSION_IMPL *session;
-
- cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_UPDATE_API_CALL_BTREE(cursor, session, modify, cbt->btree);
- WT_ERR(__cursor_checkkey(cursor));
-
- /* Check for a rational modify vector count. */
- if (nentries <= 0)
- WT_ERR_MSG(session, EINVAL,
- "Illegal modify vector with %d entries", nentries);
-
- WT_ERR(__wt_btcur_modify(cbt, entries, nentries));
-
- /*
- * Modify maintains a position, key and value. Unlike update, it's not
- * always an internal value.
- */
- WT_ASSERT(session,
- F_ISSET(cbt, WT_CBT_ACTIVE) &&
- F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT);
- WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_VALUE_SET) != 0);
-
-err: CURSOR_UPDATE_API_END(session, ret);
- return (ret);
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ CURSOR_UPDATE_API_CALL_BTREE(cursor, session, modify, cbt->btree);
+ WT_ERR(__cursor_checkkey(cursor));
+
+ /* Check for a rational modify vector count. */
+ if (nentries <= 0)
+ WT_ERR_MSG(session, EINVAL, "Illegal modify vector with %d entries", nentries);
+
+ WT_ERR(__wt_btcur_modify(cbt, entries, nentries));
+
+ /*
+ * Modify maintains a position, key and value. Unlike update, it's not always an internal value.
+ */
+ WT_ASSERT(session,
+ F_ISSET(cbt, WT_CBT_ACTIVE) && F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT);
+ WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_VALUE_SET) != 0);
+
+err:
+ CURSOR_UPDATE_API_END(session, ret);
+ return (ret);
}
/*
* __curfile_update --
- * WT_CURSOR->update method for the btree cursor type.
+ * WT_CURSOR->update method for the btree cursor type.
*/
static int
__curfile_update(WT_CURSOR *cursor)
{
- WT_CURSOR_BTREE *cbt;
- WT_DECL_RET;
- WT_SESSION_IMPL *session;
- uint64_t time_start, time_stop;
-
- cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_UPDATE_API_CALL_BTREE(cursor, session, update, cbt->btree);
- WT_ERR(__cursor_checkkey(cursor));
- WT_ERR(__cursor_checkvalue(cursor));
-
- time_start = __wt_clock(session);
- WT_ERR(__wt_btcur_update(cbt));
- time_stop = __wt_clock(session);
- __wt_stat_usecs_hist_incr_opwrite(session,
- WT_CLOCKDIFF_US(time_stop, time_start));
-
- /* Update maintains a position, key and value. */
- WT_ASSERT(session,
- F_ISSET(cbt, WT_CBT_ACTIVE) &&
- F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT &&
- F_MASK(cursor, WT_CURSTD_VALUE_SET) == WT_CURSTD_VALUE_INT);
-
-err: CURSOR_UPDATE_API_END(session, ret);
- return (ret);
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+ uint64_t time_start, time_stop;
+
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ CURSOR_UPDATE_API_CALL_BTREE(cursor, session, update, cbt->btree);
+ WT_ERR(__cursor_checkkey(cursor));
+ WT_ERR(__cursor_checkvalue(cursor));
+
+ time_start = __wt_clock(session);
+ WT_ERR(__wt_btcur_update(cbt));
+ time_stop = __wt_clock(session);
+ __wt_stat_usecs_hist_incr_opwrite(session, WT_CLOCKDIFF_US(time_stop, time_start));
+
+ /* Update maintains a position, key and value. */
+ WT_ASSERT(session, F_ISSET(cbt, WT_CBT_ACTIVE) &&
+ F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT &&
+ F_MASK(cursor, WT_CURSTD_VALUE_SET) == WT_CURSTD_VALUE_INT);
+
+err:
+ CURSOR_UPDATE_API_END(session, ret);
+ return (ret);
}
/*
* __curfile_remove --
- * WT_CURSOR->remove method for the btree cursor type.
+ * WT_CURSOR->remove method for the btree cursor type.
*/
static int
__curfile_remove(WT_CURSOR *cursor)
{
- WT_CURSOR_BTREE *cbt;
- WT_DECL_RET;
- WT_SESSION_IMPL *session;
- uint64_t time_start, time_stop;
- bool positioned;
-
- /*
- * WT_CURSOR.remove has a unique semantic, the cursor stays positioned
- * if it starts positioned, otherwise clear the cursor on completion.
- * Track if starting with a positioned cursor and pass that information
- * into the underlying Btree remove function so it tries to maintain a
- * position in the tree. This is complicated by the loop in this code
- * that restarts operations if they return prepare-conflict or restart.
- */
- positioned = F_ISSET(cursor, WT_CURSTD_KEY_INT);
-
- cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_REMOVE_API_CALL(cursor, session, cbt->btree);
- WT_ERR(__cursor_checkkey(cursor));
-
- time_start = __wt_clock(session);
- WT_ERR(__wt_btcur_remove(cbt, positioned));
- time_stop = __wt_clock(session);
- __wt_stat_usecs_hist_incr_opwrite(session,
- WT_CLOCKDIFF_US(time_stop, time_start));
-
- /* If we've lost an initial position, we must fail. */
- if (positioned && !F_ISSET(cursor, WT_CURSTD_KEY_INT))
- WT_ERR(WT_ROLLBACK);
-
- /*
- * Remove with a search-key is fire-and-forget, no position and no key.
- * Remove starting from a position maintains the position and a key,
- * but the key can end up being internal, external, or not set, there's
- * nothing to assert. There's never a value.
- */
- WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_VALUE_SET) == 0);
-
-err: CURSOR_UPDATE_API_END(session, ret);
- return (ret);
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+ uint64_t time_start, time_stop;
+ bool positioned;
+
+ /*
+ * WT_CURSOR.remove has a unique semantic, the cursor stays positioned if it starts positioned,
+ * otherwise clear the cursor on completion. Track if starting with a positioned cursor and pass
+ * that information into the underlying Btree remove function so it tries to maintain a position
+ * in the tree. This is complicated by the loop in this code that restarts operations if they
+ * return prepare-conflict or restart.
+ */
+ positioned = F_ISSET(cursor, WT_CURSTD_KEY_INT);
+
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ CURSOR_REMOVE_API_CALL(cursor, session, cbt->btree);
+ WT_ERR(__cursor_checkkey(cursor));
+
+ time_start = __wt_clock(session);
+ WT_ERR(__wt_btcur_remove(cbt, positioned));
+ time_stop = __wt_clock(session);
+ __wt_stat_usecs_hist_incr_opwrite(session, WT_CLOCKDIFF_US(time_stop, time_start));
+
+ /* If we've lost an initial position, we must fail. */
+ if (positioned && !F_ISSET(cursor, WT_CURSTD_KEY_INT))
+ WT_ERR(WT_ROLLBACK);
+
+ /*
+ * Remove with a search-key is fire-and-forget, no position and no key. Remove starting from a
+ * position maintains the position and a key, but the key can end up being internal, external,
+ * or not set, there's nothing to assert. There's never a value.
+ */
+ WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_VALUE_SET) == 0);
+
+err:
+ CURSOR_UPDATE_API_END(session, ret);
+ return (ret);
}
/*
* __curfile_reserve --
- * WT_CURSOR->reserve method for the btree cursor type.
+ * WT_CURSOR->reserve method for the btree cursor type.
*/
static int
__curfile_reserve(WT_CURSOR *cursor)
{
- WT_CURSOR_BTREE *cbt;
- WT_DECL_RET;
- WT_SESSION_IMPL *session;
-
- cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_UPDATE_API_CALL_BTREE(cursor, session, reserve, cbt->btree);
- WT_ERR(__cursor_checkkey(cursor));
-
- WT_ERR(__wt_txn_context_check(session, true));
-
- WT_ERR(__wt_btcur_reserve(cbt));
-
- /*
- * Reserve maintains a position and key, which doesn't match the library
- * API, where reserve maintains a value. Fix the API by searching after
- * each successful reserve operation.
- */
- WT_ASSERT(session,
- F_ISSET(cbt, WT_CBT_ACTIVE) &&
- F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT);
- WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_VALUE_SET) == 0);
-
-err: CURSOR_UPDATE_API_END(session, ret);
-
- /*
- * The application might do a WT_CURSOR.get_value call when we return,
- * so we need a value and the underlying functions didn't set one up.
- * For various reasons, those functions may not have done a search and
- * any previous value in the cursor might race with WT_CURSOR.reserve
- * (and in cases like LSM, the reserve never encountered the original
- * key). For simplicity, repeat the search here.
- */
- return (ret == 0 ? cursor->search(cursor) : ret);
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ CURSOR_UPDATE_API_CALL_BTREE(cursor, session, reserve, cbt->btree);
+ WT_ERR(__cursor_checkkey(cursor));
+
+ WT_ERR(__wt_txn_context_check(session, true));
+
+ WT_ERR(__wt_btcur_reserve(cbt));
+
+ /*
+ * Reserve maintains a position and key, which doesn't match the library API, where reserve
+ * maintains a value. Fix the API by searching after each successful reserve operation.
+ */
+ WT_ASSERT(session,
+ F_ISSET(cbt, WT_CBT_ACTIVE) && F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT);
+ WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_VALUE_SET) == 0);
+
+err:
+ CURSOR_UPDATE_API_END(session, ret);
+
+ /*
+ * The application might do a WT_CURSOR.get_value call when we return,
+ * so we need a value and the underlying functions didn't set one up.
+ * For various reasons, those functions may not have done a search and
+ * any previous value in the cursor might race with WT_CURSOR.reserve
+ * (and in cases like LSM, the reserve never encountered the original
+ * key). For simplicity, repeat the search here.
+ */
+ return (ret == 0 ? cursor->search(cursor) : ret);
}
/*
* __curfile_close --
- * WT_CURSOR->close method for the btree cursor type.
+ * WT_CURSOR->close method for the btree cursor type.
*/
static int
__curfile_close(WT_CURSOR *cursor)
{
- WT_CURSOR_BTREE *cbt;
- WT_CURSOR_BULK *cbulk;
- WT_DECL_RET;
- WT_SESSION_IMPL *session;
- bool dead, released;
-
- cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL_PREPARE_ALLOWED(cursor, session, close, cbt->btree);
+ WT_CURSOR_BTREE *cbt;
+ WT_CURSOR_BULK *cbulk;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+ bool dead, released;
+
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ CURSOR_API_CALL_PREPARE_ALLOWED(cursor, session, close, cbt->btree);
err:
- /* Only try to cache the cursor if there's no error. */
- if (ret == 0) {
- /*
- * If releasing the cursor fails in any way, it will be left in
- * a state that allows it to be normally closed.
- */
- ret = __wt_cursor_cache_release(session, cursor, &released);
- if (released)
- goto done;
- }
-
- dead = F_ISSET(cursor, WT_CURSTD_DEAD);
- if (F_ISSET(cursor, WT_CURSTD_BULK)) {
- /* Free the bulk-specific resources. */
- cbulk = (WT_CURSOR_BULK *)cbt;
- WT_TRET(__wt_bulk_wrapup(session, cbulk));
- __wt_buf_free(session, &cbulk->last);
- }
-
- WT_TRET(__wt_btcur_close(cbt, false));
- /* The URI is owned by the btree handle. */
- cursor->internal_uri = NULL;
-
- WT_ASSERT(session, session->dhandle == NULL ||
- session->dhandle->session_inuse > 0);
-
- __wt_cursor_close(cursor);
-
- /*
- * Note: release the data handle last so that cursor statistics are
- * updated correctly.
- */
- if (session->dhandle != NULL) {
- /* Decrement the data-source's in-use counter. */
- __wt_cursor_dhandle_decr_use(session);
-
- /*
- * If the cursor was marked dead, we got here from reopening
- * a cached cursor, which had a handle that was dead at that
- * time, so it did not obtain a lock on the handle.
- */
- if (!dead)
- WT_TRET(__wt_session_release_dhandle(session));
- }
-
-done: API_END_RET(session, ret);
+ /* Only try to cache the cursor if there's no error. */
+ if (ret == 0) {
+ /*
+ * If releasing the cursor fails in any way, it will be left in a state that allows it to be
+ * normally closed.
+ */
+ ret = __wt_cursor_cache_release(session, cursor, &released);
+ if (released)
+ goto done;
+ }
+
+ dead = F_ISSET(cursor, WT_CURSTD_DEAD);
+ if (F_ISSET(cursor, WT_CURSTD_BULK)) {
+ /* Free the bulk-specific resources. */
+ cbulk = (WT_CURSOR_BULK *)cbt;
+ WT_TRET(__wt_bulk_wrapup(session, cbulk));
+ __wt_buf_free(session, &cbulk->last);
+ }
+
+ WT_TRET(__wt_btcur_close(cbt, false));
+ /* The URI is owned by the btree handle. */
+ cursor->internal_uri = NULL;
+
+ WT_ASSERT(session, session->dhandle == NULL || session->dhandle->session_inuse > 0);
+
+ __wt_cursor_close(cursor);
+
+ /*
+ * Note: release the data handle last so that cursor statistics are updated correctly.
+ */
+ if (session->dhandle != NULL) {
+ /* Decrement the data-source's in-use counter. */
+ __wt_cursor_dhandle_decr_use(session);
+
+ /*
+ * If the cursor was marked dead, we got here from reopening a cached cursor, which had a
+ * handle that was dead at that time, so it did not obtain a lock on the handle.
+ */
+ if (!dead)
+ WT_TRET(__wt_session_release_dhandle(session));
+ }
+
+done:
+ API_END_RET(session, ret);
}
/*
* __curfile_cache --
- * WT_CURSOR->cache method for the btree cursor type.
+ * WT_CURSOR->cache method for the btree cursor type.
*/
static int
__curfile_cache(WT_CURSOR *cursor)
{
- WT_CURSOR_BTREE *cbt;
- WT_DECL_RET;
- WT_SESSION_IMPL *session;
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
- cbt = (WT_CURSOR_BTREE *)cursor;
- session = (WT_SESSION_IMPL *)cursor->session;
- cbt->dhandle = cbt->btree->dhandle;
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ session = (WT_SESSION_IMPL *)cursor->session;
+ cbt->dhandle = cbt->btree->dhandle;
- WT_TRET(__wt_cursor_cache(cursor, cbt->dhandle));
- WT_TRET(__wt_session_release_dhandle(session));
- return (ret);
+ WT_TRET(__wt_cursor_cache(cursor, cbt->dhandle));
+ WT_TRET(__wt_session_release_dhandle(session));
+ return (ret);
}
/*
* __curfile_reopen --
- * WT_CURSOR->reopen method for the btree cursor type.
+ * WT_CURSOR->reopen method for the btree cursor type.
*/
static int
__curfile_reopen(WT_CURSOR *cursor, bool check_only)
{
- WT_CURSOR_BTREE *cbt;
- WT_DATA_HANDLE *dhandle;
- WT_DECL_RET;
- WT_SESSION_IMPL *session;
- bool is_dead;
-
- cbt = (WT_CURSOR_BTREE *)cursor;
- dhandle = cbt->dhandle;
- session = (WT_SESSION_IMPL *)cursor->session;
-
- if (check_only)
- return (WT_DHANDLE_CAN_REOPEN(dhandle) ? 0 : WT_NOTFOUND);
-
- session->dhandle = dhandle;
-
- /*
- * Lock the handle: we're only interested in open handles, any other
- * state disqualifies the cache.
- */
- ret = __wt_session_lock_dhandle(session, 0, &is_dead);
- if (!is_dead && ret == 0 && !F_ISSET(dhandle, WT_DHANDLE_OPEN)) {
- WT_RET(__wt_session_release_dhandle(session));
- ret = __wt_set_return(session, EBUSY);
- }
-
- /*
- * The data handle may not be available, in which case handle it like a
- * dead handle: fail the reopen, and flag the cursor so that the handle
- * won't be unlocked when subsequently closed.
- */
- if (is_dead || ret == EBUSY) {
- F_SET(cursor, WT_CURSTD_DEAD);
- ret = WT_NOTFOUND;
- }
- __wt_cursor_reopen(cursor, dhandle);
-
- /*
- * The btree handle may have been reopened since we last accessed it.
- * Reset fields in the cursor that point to memory owned by the btree
- * handle.
- */
- if (ret == 0) {
- /* Assert a valid tree (we didn't race with eviction). */
- WT_ASSERT(session, dhandle->type == WT_DHANDLE_TYPE_BTREE);
- WT_ASSERT(session,
- ((WT_BTREE *)dhandle->handle)->root.page != NULL);
-
- cbt->btree = dhandle->handle;
- cursor->internal_uri = cbt->btree->dhandle->name;
- cursor->key_format = cbt->btree->key_format;
- cursor->value_format = cbt->btree->value_format;
- }
- return (ret);
+ WT_CURSOR_BTREE *cbt;
+ WT_DATA_HANDLE *dhandle;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+ bool is_dead;
+
+ cbt = (WT_CURSOR_BTREE *)cursor;
+ dhandle = cbt->dhandle;
+ session = (WT_SESSION_IMPL *)cursor->session;
+
+ if (check_only)
+ return (WT_DHANDLE_CAN_REOPEN(dhandle) ? 0 : WT_NOTFOUND);
+
+ session->dhandle = dhandle;
+
+ /*
+ * Lock the handle: we're only interested in open handles, any other state disqualifies the
+ * cache.
+ */
+ ret = __wt_session_lock_dhandle(session, 0, &is_dead);
+ if (!is_dead && ret == 0 && !F_ISSET(dhandle, WT_DHANDLE_OPEN)) {
+ WT_RET(__wt_session_release_dhandle(session));
+ ret = __wt_set_return(session, EBUSY);
+ }
+
+ /*
+ * The data handle may not be available, in which case handle it like a dead handle: fail the
+ * reopen, and flag the cursor so that the handle won't be unlocked when subsequently closed.
+ */
+ if (is_dead || ret == EBUSY) {
+ F_SET(cursor, WT_CURSTD_DEAD);
+ ret = WT_NOTFOUND;
+ }
+ __wt_cursor_reopen(cursor, dhandle);
+
+ /*
+ * The btree handle may have been reopened since we last accessed it. Reset fields in the cursor
+ * that point to memory owned by the btree handle.
+ */
+ if (ret == 0) {
+ /* Assert a valid tree (we didn't race with eviction). */
+ WT_ASSERT(session, dhandle->type == WT_DHANDLE_TYPE_BTREE);
+ WT_ASSERT(session, ((WT_BTREE *)dhandle->handle)->root.page != NULL);
+
+ cbt->btree = dhandle->handle;
+ cursor->internal_uri = cbt->btree->dhandle->name;
+ cursor->key_format = cbt->btree->key_format;
+ cursor->value_format = cbt->btree->value_format;
+ }
+ return (ret);
}
/*
* __curfile_create --
- * Open a cursor for a given btree handle.
+ * Open a cursor for a given btree handle.
*/
static int
-__curfile_create(WT_SESSION_IMPL *session,
- WT_CURSOR *owner, const char *cfg[], bool bulk, bool bitmap,
- WT_CURSOR **cursorp)
+__curfile_create(WT_SESSION_IMPL *session, WT_CURSOR *owner, const char *cfg[], bool bulk,
+ bool bitmap, WT_CURSOR **cursorp)
{
- WT_CURSOR_STATIC_INIT(iface,
- __wt_cursor_get_key, /* get-key */
- __wt_cursor_get_value, /* get-value */
- __wt_cursor_set_key, /* set-key */
- __wt_cursor_set_value, /* set-value */
- __curfile_compare, /* compare */
- __curfile_equals, /* equals */
- __curfile_next, /* next */
- __curfile_prev, /* prev */
- __curfile_reset, /* reset */
- __curfile_search, /* search */
- __curfile_search_near, /* search-near */
- __curfile_insert, /* insert */
- __wt_cursor_modify_notsup, /* modify */
- __curfile_update, /* update */
- __curfile_remove, /* remove */
- __curfile_reserve, /* reserve */
- __wt_cursor_reconfigure, /* reconfigure */
- __curfile_cache, /* cache */
- __curfile_reopen, /* reopen */
- __curfile_close); /* close */
- WT_BTREE *btree;
- WT_CONFIG_ITEM cval;
- WT_CURSOR *cursor;
- WT_CURSOR_BTREE *cbt;
- WT_CURSOR_BULK *cbulk;
- WT_DECL_RET;
- size_t csize;
- bool cacheable;
-
- WT_STATIC_ASSERT(offsetof(WT_CURSOR_BTREE, iface) == 0);
-
- btree = S2BT(session);
- WT_ASSERT(session, btree != NULL);
-
- csize = bulk ? sizeof(WT_CURSOR_BULK) : sizeof(WT_CURSOR_BTREE);
- cacheable = F_ISSET(session, WT_SESSION_CACHE_CURSORS) && !bulk;
-
- WT_RET(__wt_calloc(session, 1, csize, &cbt));
- cursor = (WT_CURSOR *)cbt;
- *cursor = iface;
- cursor->session = (WT_SESSION *)session;
- cursor->internal_uri = btree->dhandle->name;
- cursor->key_format = btree->key_format;
- cursor->value_format = btree->value_format;
- cbt->btree = btree;
-
- /*
- * Increment the data-source's in-use counter; done now because closing
- * the cursor will decrement it, and all failure paths from here close
- * the cursor.
- */
- __wt_cursor_dhandle_incr_use(session);
-
- if (session->dhandle->checkpoint != NULL)
- F_SET(cbt, WT_CBT_NO_TXN);
-
- if (bulk) {
- F_SET(cursor, WT_CURSTD_BULK);
-
- cbulk = (WT_CURSOR_BULK *)cbt;
-
- /* Optionally skip the validation of each bulk-loaded key. */
- WT_ERR(__wt_config_gets_def(
- session, cfg, "skip_sort_check", 0, &cval));
- WT_ERR(__wt_curbulk_init(
- session, cbulk, bitmap, cval.val == 0 ? 0 : 1));
- }
-
- /*
- * Random retrieval, row-store only.
- * Random retrieval cursors support a limited set of methods.
- */
- WT_ERR(__wt_config_gets_def(session, cfg, "next_random", 0, &cval));
- if (cval.val != 0) {
- if (WT_CURSOR_RECNO(cursor))
- WT_ERR_MSG(session, ENOTSUP,
- "next_random configuration not supported for "
- "column-store objects");
-
- __wt_cursor_set_notsup(cursor);
- cursor->next = __wt_curfile_next_random;
- cursor->reset = __curfile_reset;
-
- WT_ERR(__wt_config_gets_def(
- session, cfg, "next_random_sample_size", 0, &cval));
- if (cval.val != 0)
- cbt->next_random_sample_size = (u_int)cval.val;
- cacheable = false;
- }
-
- WT_ERR(__wt_config_gets_def(session, cfg, "read_once", 0, &cval));
- if (cval.val != 0)
- F_SET(cbt, WT_CBT_READ_ONCE);
-
- /* Underlying btree initialization. */
- __wt_btcur_open(cbt);
-
- /*
- * WT_CURSOR.modify supported on 'S' and 'u' value formats, but the
- * fast-path through the btree code requires log file format changes,
- * it's not available in all versions.
- */
- if ((WT_STREQ(cursor->value_format, "S") ||
- WT_STREQ(cursor->value_format, "u")) &&
- S2C(session)->compat_major >= WT_LOG_V2_MAJOR)
- cursor->modify = __curfile_modify;
-
- /*
- * WiredTiger.wt should not be cached, doing so interferes
- * with named checkpoints.
- */
- if (cacheable && strcmp(WT_METAFILE_URI, cursor->internal_uri) != 0)
- F_SET(cursor, WT_CURSTD_CACHEABLE);
-
- WT_ERR(__wt_cursor_init(
- cursor, cursor->internal_uri, owner, cfg, cursorp));
-
- WT_STAT_CONN_INCR(session, cursor_create);
- WT_STAT_DATA_INCR(session, cursor_create);
-
- if (0) {
+ WT_CURSOR_STATIC_INIT(iface, __wt_cursor_get_key, /* get-key */
+ __wt_cursor_get_value, /* get-value */
+ __wt_cursor_set_key, /* set-key */
+ __wt_cursor_set_value, /* set-value */
+ __curfile_compare, /* compare */
+ __curfile_equals, /* equals */
+ __curfile_next, /* next */
+ __curfile_prev, /* prev */
+ __curfile_reset, /* reset */
+ __curfile_search, /* search */
+ __curfile_search_near, /* search-near */
+ __curfile_insert, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
+ __curfile_update, /* update */
+ __curfile_remove, /* remove */
+ __curfile_reserve, /* reserve */
+ __wt_cursor_reconfigure, /* reconfigure */
+ __curfile_cache, /* cache */
+ __curfile_reopen, /* reopen */
+ __curfile_close); /* close */
+ WT_BTREE *btree;
+ WT_CONFIG_ITEM cval;
+ WT_CURSOR *cursor;
+ WT_CURSOR_BTREE *cbt;
+ WT_CURSOR_BULK *cbulk;
+ WT_DECL_RET;
+ size_t csize;
+ bool cacheable;
+
+ WT_STATIC_ASSERT(offsetof(WT_CURSOR_BTREE, iface) == 0);
+
+ btree = S2BT(session);
+ WT_ASSERT(session, btree != NULL);
+
+ csize = bulk ? sizeof(WT_CURSOR_BULK) : sizeof(WT_CURSOR_BTREE);
+ cacheable = F_ISSET(session, WT_SESSION_CACHE_CURSORS) && !bulk;
+
+ WT_RET(__wt_calloc(session, 1, csize, &cbt));
+ cursor = (WT_CURSOR *)cbt;
+ *cursor = iface;
+ cursor->session = (WT_SESSION *)session;
+ cursor->internal_uri = btree->dhandle->name;
+ cursor->key_format = btree->key_format;
+ cursor->value_format = btree->value_format;
+ cbt->btree = btree;
+
+ /*
+ * Increment the data-source's in-use counter; done now because closing the cursor will
+ * decrement it, and all failure paths from here close the cursor.
+ */
+ __wt_cursor_dhandle_incr_use(session);
+
+ if (session->dhandle->checkpoint != NULL)
+ F_SET(cbt, WT_CBT_NO_TXN);
+
+ if (bulk) {
+ F_SET(cursor, WT_CURSTD_BULK);
+
+ cbulk = (WT_CURSOR_BULK *)cbt;
+
+ /* Optionally skip the validation of each bulk-loaded key. */
+ WT_ERR(__wt_config_gets_def(session, cfg, "skip_sort_check", 0, &cval));
+ WT_ERR(__wt_curbulk_init(session, cbulk, bitmap, cval.val == 0 ? 0 : 1));
+ }
+
+ /*
+ * Random retrieval, row-store only. Random retrieval cursors support a limited set of methods.
+ */
+ WT_ERR(__wt_config_gets_def(session, cfg, "next_random", 0, &cval));
+ if (cval.val != 0) {
+ if (WT_CURSOR_RECNO(cursor))
+ WT_ERR_MSG(session, ENOTSUP,
+ "next_random configuration not supported for "
+ "column-store objects");
+
+ __wt_cursor_set_notsup(cursor);
+ cursor->next = __wt_curfile_next_random;
+ cursor->reset = __curfile_reset;
+
+ WT_ERR(__wt_config_gets_def(session, cfg, "next_random_sample_size", 0, &cval));
+ if (cval.val != 0)
+ cbt->next_random_sample_size = (u_int)cval.val;
+ cacheable = false;
+ }
+
+ WT_ERR(__wt_config_gets_def(session, cfg, "read_once", 0, &cval));
+ if (cval.val != 0)
+ F_SET(cbt, WT_CBT_READ_ONCE);
+
+ /* Underlying btree initialization. */
+ __wt_btcur_open(cbt);
+
+ /*
+ * WT_CURSOR.modify supported on 'S' and 'u' value formats, but the fast-path through the btree
+ * code requires log file format changes, it's not available in all versions.
+ */
+ if ((WT_STREQ(cursor->value_format, "S") || WT_STREQ(cursor->value_format, "u")) &&
+ S2C(session)->compat_major >= WT_LOG_V2_MAJOR)
+ cursor->modify = __curfile_modify;
+
+ /*
+ * WiredTiger.wt should not be cached, doing so interferes with named checkpoints.
+ */
+ if (cacheable && strcmp(WT_METAFILE_URI, cursor->internal_uri) != 0)
+ F_SET(cursor, WT_CURSTD_CACHEABLE);
+
+ WT_ERR(__wt_cursor_init(cursor, cursor->internal_uri, owner, cfg, cursorp));
+
+ WT_STAT_CONN_INCR(session, cursor_create);
+ WT_STAT_DATA_INCR(session, cursor_create);
+
+ if (0) {
err:
- /*
- * Our caller expects to release the data handle if we fail.
- * Disconnect it from the cursor before closing.
- */
- __wt_cursor_dhandle_decr_use(session);
- cbt->btree = NULL;
- WT_TRET(__curfile_close(cursor));
- *cursorp = NULL;
- }
-
- return (ret);
+ /*
+ * Our caller expects to release the data handle if we fail. Disconnect it from the cursor
+ * before closing.
+ */
+ __wt_cursor_dhandle_decr_use(session);
+ cbt->btree = NULL;
+ WT_TRET(__curfile_close(cursor));
+ *cursorp = NULL;
+ }
+
+ return (ret);
}
/*
* __wt_curfile_open --
- * WT_SESSION->open_cursor method for the btree cursor type.
+ * WT_SESSION->open_cursor method for the btree cursor type.
*/
int
-__wt_curfile_open(WT_SESSION_IMPL *session, const char *uri,
- WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp)
+__wt_curfile_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[],
+ WT_CURSOR **cursorp)
{
- WT_CONFIG_ITEM cval;
- WT_DECL_RET;
- uint32_t flags;
- bool bitmap, bulk, checkpoint_wait;
-
- bitmap = bulk = false;
- checkpoint_wait = true;
- flags = 0;
-
- /*
- * Decode the bulk configuration settings. In memory databases
- * ignore bulk load.
- */
- if (!F_ISSET(S2C(session), WT_CONN_IN_MEMORY)) {
- WT_RET(__wt_config_gets_def(session, cfg, "bulk", 0, &cval));
- if (cval.type == WT_CONFIG_ITEM_BOOL ||
- (cval.type == WT_CONFIG_ITEM_NUM &&
- (cval.val == 0 || cval.val == 1))) {
- bitmap = false;
- bulk = cval.val != 0;
- } else if (WT_STRING_MATCH("bitmap", cval.str, cval.len))
- bitmap = bulk = true;
- /*
- * Unordered bulk insert is a special case used
- * internally by index creation on existing tables. It
- * doesn't enforce any special semantics at the file
- * level. It primarily exists to avoid some locking
- * problems between LSM and index creation.
- */
- else if (!WT_STRING_MATCH("unordered", cval.str, cval.len))
- WT_RET_MSG(session, EINVAL,
- "Value for 'bulk' must be a boolean or 'bitmap'");
-
- if (bulk) {
- WT_RET(__wt_config_gets(session,
- cfg, "checkpoint_wait", &cval));
- checkpoint_wait = cval.val != 0;
- }
- }
-
- /* Bulk handles require exclusive access. */
- if (bulk)
- LF_SET(WT_BTREE_BULK | WT_DHANDLE_EXCLUSIVE);
-
- WT_ASSERT(session, WT_PREFIX_MATCH(uri, "file:"));
-
- /* Get the handle and lock it while the cursor is using it. */
- /*
- * If we are opening exclusive and don't want a bulk cursor
- * open to fail with EBUSY due to a database-wide checkpoint,
- * get the handle while holding the checkpoint lock.
- */
- if (LF_ISSET(WT_DHANDLE_EXCLUSIVE) && checkpoint_wait)
- WT_WITH_CHECKPOINT_LOCK(session,
- ret = __wt_session_get_btree_ckpt(
- session, uri, cfg, flags));
- else
- ret = __wt_session_get_btree_ckpt(
- session, uri, cfg, flags);
- WT_RET(ret);
-
- WT_ERR(__curfile_create(session, owner, cfg, bulk, bitmap, cursorp));
-
- return (0);
+ WT_CONFIG_ITEM cval;
+ WT_DECL_RET;
+ uint32_t flags;
+ bool bitmap, bulk, checkpoint_wait;
+
+ bitmap = bulk = false;
+ checkpoint_wait = true;
+ flags = 0;
+
+ /*
+ * Decode the bulk configuration settings. In memory databases ignore bulk load.
+ */
+ if (!F_ISSET(S2C(session), WT_CONN_IN_MEMORY)) {
+ WT_RET(__wt_config_gets_def(session, cfg, "bulk", 0, &cval));
+ if (cval.type == WT_CONFIG_ITEM_BOOL ||
+ (cval.type == WT_CONFIG_ITEM_NUM && (cval.val == 0 || cval.val == 1))) {
+ bitmap = false;
+ bulk = cval.val != 0;
+ } else if (WT_STRING_MATCH("bitmap", cval.str, cval.len))
+ bitmap = bulk = true;
+ /*
+ * Unordered bulk insert is a special case used internally by index creation on existing
+ * tables. It doesn't enforce any special semantics at the file level. It primarily exists
+ * to avoid some locking problems between LSM and index creation.
+ */
+ else if (!WT_STRING_MATCH("unordered", cval.str, cval.len))
+ WT_RET_MSG(session, EINVAL, "Value for 'bulk' must be a boolean or 'bitmap'");
+
+ if (bulk) {
+ WT_RET(__wt_config_gets(session, cfg, "checkpoint_wait", &cval));
+ checkpoint_wait = cval.val != 0;
+ }
+ }
+
+ /* Bulk handles require exclusive access. */
+ if (bulk)
+ LF_SET(WT_BTREE_BULK | WT_DHANDLE_EXCLUSIVE);
+
+ WT_ASSERT(session, WT_PREFIX_MATCH(uri, "file:"));
+
+ /* Get the handle and lock it while the cursor is using it. */
+ /*
+ * If we are opening exclusive and don't want a bulk cursor open to fail with EBUSY due to a
+ * database-wide checkpoint, get the handle while holding the checkpoint lock.
+ */
+ if (LF_ISSET(WT_DHANDLE_EXCLUSIVE) && checkpoint_wait)
+ WT_WITH_CHECKPOINT_LOCK(
+ session, ret = __wt_session_get_btree_ckpt(session, uri, cfg, flags));
+ else
+ ret = __wt_session_get_btree_ckpt(session, uri, cfg, flags);
+ WT_RET(ret);
+
+ WT_ERR(__curfile_create(session, owner, cfg, bulk, bitmap, cursorp));
+
+ return (0);
err:
- /* If the cursor could not be opened, release the handle. */
- WT_TRET(__wt_session_release_dhandle(session));
- return (ret);
+ /* If the cursor could not be opened, release the handle. */
+ WT_TRET(__wt_session_release_dhandle(session));
+ return (ret);
}