summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Bostic <keith@wiredtiger.com>2013-09-10 12:26:37 -0400
committerKeith Bostic <keith@wiredtiger.com>2013-09-10 12:26:37 -0400
commit2bd115e75796e923c4ace79922762dfefd5619d4 (patch)
treeb2cd43cc5bdcfd5b17617d670c28fdc6181a3d82 /src
parentc7fbd72c5f25a8dd78e6a2679659af3b65b43dc7 (diff)
downloadmongo-2bd115e75796e923c4ace79922762dfefd5619d4.tar.gz
Change WT_CURSOR::insert to not hold a position/resources in the tree on
success. Add additional wording that WT_CURSOR::reset should be called after any of the WT_CURSOR search, search-near, update or remove methods, once the cursor is no longer being used to iterate or retrieve values. Closes #587.
Diffstat (limited to 'src')
-rw-r--r--src/btree/bt_cursor.c4
-rw-r--r--src/cursor/cur_file.c16
-rw-r--r--src/docs/cursor-ops.dox7
-rw-r--r--src/docs/upgrading.dox14
-rw-r--r--src/include/wiredtiger.in43
-rw-r--r--src/lsm/lsm_cursor.c12
6 files changed, 81 insertions, 15 deletions
diff --git a/src/btree/bt_cursor.c b/src/btree/bt_cursor.c
index d0dacf1adb2..ae3452c2aa7 100644
--- a/src/btree/bt_cursor.c
+++ b/src/btree/bt_cursor.c
@@ -327,9 +327,9 @@ retry: WT_RET(__cursor_func_init(cbt, 1));
err: if (ret == WT_RESTART)
goto retry;
- /* If successful, point the cursor at internal copies of the data. */
+ /* Insert doesn't maintain a position across calls, clear resources. */
if (ret == 0)
- ret = __wt_kv_return(session, cbt);
+ WT_TRET(__cursor_leave(cbt));
if (ret != 0)
WT_TRET(__cursor_error_resolve(cbt));
return (ret);
diff --git a/src/cursor/cur_file.c b/src/cursor/cur_file.c
index 76b03d51632..2e8abdcf60a 100644
--- a/src/cursor/cur_file.c
+++ b/src/cursor/cur_file.c
@@ -222,6 +222,22 @@ __curfile_insert(WT_CURSOR *cursor)
WT_BTREE_CURSOR_SAVE_AND_RESTORE(cursor, __wt_btcur_insert(cbt), ret);
+ /*
+ * Insert is the one cursor operation that doesn't end with the cursor
+ * pointing to an on-page item. The standard macro handles errors
+ * correctly, but we need to leave the application cursor unchanged in
+ * the case of success, except for column-store appends, where we are
+ * returning a key.
+ */
+ if (ret == 0) {
+ if (!F_ISSET(cursor, WT_CURSTD_APPEND)) {
+ F_SET(cursor, WT_CURSTD_KEY_EXT);
+ F_CLR(cursor, WT_CURSTD_KEY_INT);
+ }
+ F_SET(cursor, WT_CURSTD_VALUE_EXT);
+ F_CLR(cursor, WT_CURSTD_VALUE_INT);
+ }
+
err: CURSOR_UPDATE_API_END(session, ret);
return (ret);
}
diff --git a/src/docs/cursor-ops.dox b/src/docs/cursor-ops.dox
index ecdccacd5ac..ef8a7b20499 100644
--- a/src/docs/cursor-ops.dox
+++ b/src/docs/cursor-ops.dox
@@ -121,9 +121,10 @@ for the backup, config and statistics cursor types.
When applications pass pointers to WT_CURSOR::set_key or WT_CURSOR::set_value,
which can be a WT_ITEM or a string, the application is required to keep
-the memory valid until the next operation that successfully positions the
-cursor. These operations are WT_CURSOR::insert, WT_CURSOR::remove,
-WT_CURSOR::search, WT_CURSOR::search_near and WT_CURSOR::update.
+the memory valid until the next operation that successfully positions
+the cursor. These operations are WT_CURSOR::remove, WT_CURSOR::search,
+WT_CURSOR::search_near and WT_CURSOR::update, but <b>do not include</b>
+WT_CURSOR::insert, as it does not position the cursor.
If such an operation fails (for example, due to a ::WT_DEADLOCK error),
it may be retried without calling WT_CURSOR::set_key or
diff --git a/src/docs/upgrading.dox b/src/docs/upgrading.dox
index e61d3523ba5..255bc8f8879 100644
--- a/src/docs/upgrading.dox
+++ b/src/docs/upgrading.dox
@@ -1,5 +1,19 @@
/*! @page upgrading Upgrading WiredTiger applications
+@section version_165 Upgrading to Version 1.6.5
+<dl>
+
+<dt>WT_CURSOR::insert behavior</dt>
+<dd>
+In previous releases, the WT_CURSOR::insert ended positioned at the inserted
+record. To minimize the cursor resources held by applications inserting many
+records, the WT_CURSOR::insert method has been changed to end without any
+position. Application insert cursors should be reviewed to confirm they do
+not attempt to iterate after an insert.
+</dd>
+
+</dl>
+<hr>
@section version_164 Upgrading to Version 1.6.4
<dl>
diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in
index e7776f285c3..cfa53e304fe 100644
--- a/src/include/wiredtiger.in
+++ b/src/include/wiredtiger.in
@@ -293,27 +293,48 @@ struct __wt_cursor {
int __F(reset)(WT_CURSOR *cursor);
/*!
- * Move to the record matching the key. The key must first be set.
+ * Return the record matching the key. The key must first be set.
*
* @snippet ex_all.c Search for an exact match
*
+ * On success, the cursor ends positioned at the returned record; to
+ * minimize cursor resources, the WT_CURSOR::reset method should be
+ * called as soon as the record has been retrieved and the cursor no
+ * longer needs that position.
+ *
* @param cursor the cursor handle
* @errors
*/
int __F(search)(WT_CURSOR *cursor);
/*!
- * Move to the record matching the key if it exists, or a record that
- * would be adjacent. Either the smallest record larger than the key
- * or the largest record smaller than the key (in other words, a
- * logically adjacent key). The key must first be set.
+ * Return the record matching the key if it exists, or an adjacent
+ * record. An adjacent record is either the smallest record larger
+ * than the key or the largest record smaller than the key (in other
+ * words, a logically adjacent key).
+ *
+ * The key must first be set.
+ *
+ * An example of a search for an exact or adjacent match:
*
* @snippet ex_all.c Search for an exact or adjacent match
*
+ * An example of a forward scan through the table, where all keys
+ * greater than or equal to a specified prefix are included in the
+ * scan:
+ *
* @snippet ex_all.c Forward scan greater than or equal
*
+ * An example of a backward scan through the table, where all keys
+ * less than a specified prefix are included in the scan:
+ *
* @snippet ex_all.c Backward scan less than
*
+ * On success, the cursor ends positioned at the returned record; to
+ * minimize cursor resources, the WT_CURSOR::reset method should be
+ * called as soon as the record has been retrieved and the cursor no
+ * longer needs that position.
+ *
* @param cursor the cursor handle
* @param exactp the status of the search: 0 if an exact match is
* found, < 0 if a smaller key is returned, > 0 if a larger key is
@@ -349,6 +370,10 @@ struct __wt_cursor {
*
* @snippet ex_all.c Insert a new record and assign a record number
*
+ * The cursor ends with no position, and a subsequent call to the
+ * WT_CURSOR::next (WT_CURSOR::prev) method will iterate from the
+ * beginning (end) of the table.
+ *
* Inserting a new record after the current maximum record in a
* fixed-length bit field column-store (that is, a store with an
* 'r' type key and 't' type value) may implicitly create the missing
@@ -381,6 +406,10 @@ struct __wt_cursor {
*
* @snippet ex_all.c Update an existing record and fail if DNE
*
+ * On success, the cursor ends positioned at the modified record; to
+ * minimize cursor resources, the WT_CURSOR::reset method should be
+ * called as soon as the cursor no longer needs that position.
+ *
* @param cursor the cursor handle
* @errors
* In particular, if \c overwrite is not configured and no record with
@@ -406,6 +435,10 @@ struct __wt_cursor {
* (that is, a store with an 'r' type key and 't' type value) is
* identical to setting the record's value to 0.
*
+ * On success, the cursor ends positioned at the removed record; to
+ * minimize cursor resources, the WT_CURSOR::reset method should be
+ * called as soon as the cursor no longer needs that position.
+ *
* @param cursor the cursor handle
* @errors
* In particular, if \c overwrite is not configured and no record with
diff --git a/src/lsm/lsm_cursor.c b/src/lsm/lsm_cursor.c
index 0f242777693..25d70e7be6a 100644
--- a/src/lsm/lsm_cursor.c
+++ b/src/lsm/lsm_cursor.c
@@ -964,7 +964,7 @@ err: API_END(session);
*/
static inline int
__clsm_put(WT_SESSION_IMPL *session,
- WT_CURSOR_LSM *clsm, const WT_ITEM *key, const WT_ITEM *value)
+ WT_CURSOR_LSM *clsm, const WT_ITEM *key, const WT_ITEM *value, int insert)
{
WT_CURSOR *c, *primary;
WT_DECL_RET;
@@ -995,7 +995,7 @@ __clsm_put(WT_SESSION_IMPL *session,
c = clsm->cursors[(clsm->nchunks - i) - 1];
c->set_key(c, key);
c->set_value(c, value);
- WT_RET(c->insert(c));
+ WT_RET(insert ? c->insert(c) : c->update(c));
}
/*
@@ -1082,7 +1082,7 @@ __clsm_insert(WT_CURSOR *cursor)
return (ret);
}
- ret = __clsm_put(session, clsm, &cursor->key, &cursor->value);
+ ret = __clsm_put(session, clsm, &cursor->key, &cursor->value, 1);
err: WT_LSM_UPDATE_LEAVE(clsm, session, ret);
return (ret);
@@ -1105,7 +1105,8 @@ __clsm_update(WT_CURSOR *cursor)
if (F_ISSET(cursor, WT_CURSTD_OVERWRITE) ||
(ret = __clsm_search(cursor)) == 0)
- ret = __clsm_put(session, clsm, &cursor->key, &cursor->value);
+ ret = __clsm_put(
+ session, clsm, &cursor->key, &cursor->value, 0);
err: WT_LSM_UPDATE_LEAVE(clsm, session, ret);
return (ret);
@@ -1127,7 +1128,8 @@ __clsm_remove(WT_CURSOR *cursor)
if (F_ISSET(cursor, WT_CURSTD_OVERWRITE) ||
(ret = __clsm_search(cursor)) == 0)
- ret = __clsm_put(session, clsm, &cursor->key, &__lsm_tombstone);
+ ret = __clsm_put(
+ session, clsm, &cursor->key, &__lsm_tombstone, 0);
err: WT_LSM_UPDATE_LEAVE(clsm, session, ret);
return (ret);