summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/btree/bt_curprev.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/src/btree/bt_curprev.c')
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_curprev.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/src/third_party/wiredtiger/src/btree/bt_curprev.c b/src/third_party/wiredtiger/src/btree/bt_curprev.c
index 7517eac77d8..867a46201a4 100644
--- a/src/third_party/wiredtiger/src/btree/bt_curprev.c
+++ b/src/third_party/wiredtiger/src/btree/bt_curprev.c
@@ -441,10 +441,12 @@ restart_read:
/*
* __cursor_row_prev --
- * Move to the previous row-store item.
+ * Move to the previous row-store item. Taking an optional prefix item for a special case of
+ * search near.
*/
static inline int
-__cursor_row_prev(WT_CURSOR_BTREE *cbt, bool newpage, bool restart, size_t *skippedp)
+__cursor_row_prev(
+ WT_CURSOR_BTREE *cbt, bool newpage, bool restart, size_t *skippedp, WT_ITEM *prefix)
{
WT_CELL_UNPACK_KV kpack;
WT_INSERT *ins;
@@ -553,6 +555,17 @@ restart_read_insert:
restart_read_page:
rip = &page->pg_row[cbt->slot];
WT_RET(__cursor_row_slot_key_return(cbt, rip, &kpack, &kpack_used));
+ /*
+ * If the cursor has prefix search configured we can early exit here if the key we are
+ * visiting is before our prefix.
+ */
+ if (F_ISSET(&cbt->iface, WT_CURSTD_PREFIX_SEARCH) && prefix != NULL &&
+ __wt_prefix_match(prefix, &cbt->iface.key) > 0) {
+ /* It is not okay for the user to have a custom collator. */
+ WT_ASSERT(session, CUR2BT(cbt)->collator == NULL);
+ WT_STAT_CONN_DATA_INCR(session, cursor_search_near_prefix_fast_paths);
+ return (WT_NOTFOUND);
+ }
WT_RET(__wt_txn_read(
session, cbt, &cbt->iface.key, WT_RECNO_OOB, WT_ROW_UPDATE(page, rip), NULL));
if (cbt->upd_value->type == WT_UPDATE_INVALID) {
@@ -572,11 +585,11 @@ restart_read_page:
}
/*
- * __wt_btcur_prev --
+ * __wt_btcur_prev_prefix --
* Move to the previous record in the tree.
*/
int
-__wt_btcur_prev(WT_CURSOR_BTREE *cbt, bool truncating)
+__wt_btcur_prev_prefix(WT_CURSOR_BTREE *cbt, WT_ITEM *prefix, bool truncating)
{
WT_CURSOR *cursor;
WT_DECL_RET;
@@ -653,8 +666,14 @@ __wt_btcur_prev(WT_CURSOR_BTREE *cbt, bool truncating)
total_skipped += skipped;
break;
case WT_PAGE_ROW_LEAF:
- ret = __cursor_row_prev(cbt, newpage, restart, &skipped);
+ ret = __cursor_row_prev(cbt, newpage, restart, &skipped, prefix);
total_skipped += skipped;
+ /*
+ * We can directly return WT_NOTFOUND here as the caller will reset the cursor for
+ * us, this way we don't leave the cursor positioned after returning WT_NOTFOUND.
+ */
+ if (ret == WT_NOTFOUND && F_ISSET(&cbt->iface, WT_CURSTD_PREFIX_SEARCH))
+ return (WT_NOTFOUND);
break;
default:
WT_ERR(__wt_illegal_value(session, page->type));
@@ -726,3 +745,13 @@ err:
F_CLR(cbt, WT_CBT_ITERATE_RETRY_NEXT);
return (ret);
}
+
+/*
+ * __wt_btcur_prev --
+ * Move to the previous record in the tree.
+ */
+int
+__wt_btcur_prev(WT_CURSOR_BTREE *cbt, bool truncating)
+{
+ return (__wt_btcur_prev_prefix(cbt, NULL, truncating));
+}