diff options
author | Keith Bostic <keith@wiredtiger.com> | 2013-09-10 12:26:37 -0400 |
---|---|---|
committer | Keith Bostic <keith@wiredtiger.com> | 2013-09-10 12:26:37 -0400 |
commit | 2bd115e75796e923c4ace79922762dfefd5619d4 (patch) | |
tree | b2cd43cc5bdcfd5b17617d670c28fdc6181a3d82 /src | |
parent | c7fbd72c5f25a8dd78e6a2679659af3b65b43dc7 (diff) | |
download | mongo-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.c | 4 | ||||
-rw-r--r-- | src/cursor/cur_file.c | 16 | ||||
-rw-r--r-- | src/docs/cursor-ops.dox | 7 | ||||
-rw-r--r-- | src/docs/upgrading.dox | 14 | ||||
-rw-r--r-- | src/include/wiredtiger.in | 43 | ||||
-rw-r--r-- | src/lsm/lsm_cursor.c | 12 |
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); |