diff options
Diffstat (limited to 'src/third_party/wiredtiger/src/btree/bt_curprev.c')
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_curprev.c | 39 |
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)); +} |