summaryrefslogtreecommitdiff
path: root/src/session/session_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/session/session_api.c')
-rw-r--r--src/session/session_api.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/src/session/session_api.c b/src/session/session_api.c
index e54553aa071..e95bea3f75b 100644
--- a/src/session/session_api.c
+++ b/src/session/session_api.c
@@ -570,7 +570,9 @@ __session_truncate(WT_SESSION *wt_session,
WT_DECL_RET;
WT_SESSION_IMPL *session;
WT_CURSOR *cursor;
- int cmp;
+ int cmp, local_start;
+
+ local_start = 0;
session = (WT_SESSION_IMPL *)wt_session;
SESSION_TXN_API_CALL(session, truncate, config, cfg);
@@ -642,9 +644,7 @@ __session_truncate(WT_SESSION *wt_session,
* what records currently appear in the object. For this reason, do a
* search-near, rather than a search. Additionally, we have to correct
* after calling search-near, to position the start/stop cursors on the
- * next record greater than/less than the original key. If the cursors
- * hit the beginning/end of the object, or the start/stop keys cross,
- * we're done, the range must be empty.
+ * next record greater than/less than the original key.
*/
if (start != NULL) {
WT_ERR(start->search_near(start, &cmp));
@@ -659,12 +659,28 @@ __session_truncate(WT_SESSION *wt_session,
WT_ERR_NOTFOUND_OK(ret);
goto done;
}
+ }
- if (start != NULL) {
- WT_ERR(start->compare(start, stop, &cmp));
- if (cmp > 0)
- goto done;
- }
+ /*
+ * We always truncate in the forward direction because the underlying
+ * data structures can move through pages faster forward than backward.
+ * If we don't have a start cursor, create one and position it at the
+ * first record.
+ */
+ if (start == NULL) {
+ WT_ERR(__session_open_cursor(
+ wt_session, stop->uri, NULL, NULL, &start));
+ local_start = 1;
+ WT_ERR(start->next(start));
+ }
+
+ /*
+ * If the start/stop keys cross, we're done, the range must be empty.
+ */
+ if (stop != NULL) {
+ WT_ERR(start->compare(start, stop, &cmp));
+ if (cmp > 0)
+ goto done;
}
WT_ERR(__wt_schema_range_truncate(session, start, stop));
@@ -673,6 +689,12 @@ done:
err: TXN_API_END_RETRY(session, ret, 0);
/*
+ * Close any locally-opened start cursor.
+ */
+ if (local_start)
+ WT_TRET(start->close(start));
+
+ /*
* Only map WT_NOTFOUND to ENOENT if a URI was specified.
*/
return (ret == WT_NOTFOUND && uri != NULL ? ENOENT : ret);