summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Gorrod <alexander.gorrod@mongodb.com>2017-05-25 10:50:53 -0400
committerGitHub <noreply@github.com>2017-05-25 10:50:53 -0400
commit4641a4586fd18925b3e91881b7c5fd7a203c337b (patch)
treedda590b7d49981bc868d990384b3cfb756a33c12 /src
parentf7ac27044ef7a0332c68be16d51ad25077d4f8b2 (diff)
downloadmongo-4641a4586fd18925b3e91881b7c5fd7a203c337b.tar.gz
WT-2972 Add interface allowing partial updates to existing values (#3435)
Diffstat (limited to 'src')
-rw-r--r--src/btree/bt_curnext.c8
-rw-r--r--src/btree/bt_curprev.c8
-rw-r--r--src/btree/bt_cursor.c87
-rw-r--r--src/btree/bt_debug.c4
-rw-r--r--src/btree/bt_delete.c2
-rw-r--r--src/btree/bt_read.c16
-rw-r--r--src/btree/bt_split.c6
-rw-r--r--src/btree/bt_stat.c20
-rw-r--r--src/btree/col_modify.c17
-rw-r--r--src/btree/row_modify.c20
-rw-r--r--src/cursor/cur_backup.c1
-rw-r--r--src/cursor/cur_config.c1
-rw-r--r--src/cursor/cur_ds.c1
-rw-r--r--src/cursor/cur_dump.c1
-rw-r--r--src/cursor/cur_file.c6
-rw-r--r--src/cursor/cur_index.c1
-rw-r--r--src/cursor/cur_join.c2
-rw-r--r--src/cursor/cur_log.c1
-rw-r--r--src/cursor/cur_metadata.c1
-rw-r--r--src/cursor/cur_stat.c1
-rw-r--r--src/cursor/cur_std.c115
-rw-r--r--src/cursor/cur_table.c2
-rw-r--r--src/docs/Doxyfile1
-rw-r--r--src/include/btmem.h37
-rw-r--r--src/include/cursor.h2
-rw-r--r--src/include/extern.h7
-rw-r--r--src/include/log.h2
-rw-r--r--src/include/lsm.h4
-rw-r--r--src/include/mutex.h4
-rw-r--r--src/include/mutex.i8
-rw-r--r--src/include/schema.h2
-rw-r--r--src/include/stat.h4
-rw-r--r--src/include/txn.i2
-rw-r--r--src/include/verify_build.h1
-rw-r--r--src/include/wiredtiger.in406
-rw-r--r--src/lsm/lsm_cursor.c1
-rw-r--r--src/reconcile/rec_write.c23
-rw-r--r--src/support/stat.c14
-rw-r--r--src/txn/txn.c2
-rw-r--r--src/txn/txn_log.c6
40 files changed, 545 insertions, 302 deletions
diff --git a/src/btree/bt_curnext.c b/src/btree/bt_curnext.c
index 091b9345713..7b92a58991d 100644
--- a/src/btree/bt_curnext.c
+++ b/src/btree/bt_curnext.c
@@ -142,7 +142,7 @@ new_page: if (cbt->ins == NULL)
__cursor_set_recno(cbt, WT_INSERT_RECNO(cbt->ins));
if ((upd = __wt_txn_read(session, cbt->ins->upd)) == NULL)
continue;
- if (WT_UPDATE_DELETED_ISSET(upd)) {
+ if (upd->type == WT_UPDATE_DELETED) {
if (__wt_txn_visible_all(session, upd->txnid))
++cbt->page_deleted_count;
continue;
@@ -205,7 +205,7 @@ new_page: /* Find the matching WT_COL slot. */
upd = cbt->ins == NULL ?
NULL : __wt_txn_read(session, cbt->ins->upd);
if (upd != NULL) {
- if (WT_UPDATE_DELETED_ISSET(upd)) {
+ if (upd->type == WT_UPDATE_DELETED) {
if (__wt_txn_visible_all(session, upd->txnid))
++cbt->page_deleted_count;
continue;
@@ -325,7 +325,7 @@ __cursor_row_next(WT_CURSOR_BTREE *cbt, bool newpage)
new_insert: if ((ins = cbt->ins) != NULL) {
if ((upd = __wt_txn_read(session, ins->upd)) == NULL)
continue;
- if (WT_UPDATE_DELETED_ISSET(upd)) {
+ if (upd->type == WT_UPDATE_DELETED) {
if (__wt_txn_visible_all(session, upd->txnid))
++cbt->page_deleted_count;
continue;
@@ -358,7 +358,7 @@ new_insert: if ((ins = cbt->ins) != NULL) {
cbt->slot = cbt->row_iteration_slot / 2 - 1;
rip = &page->pg_row[cbt->slot];
upd = __wt_txn_read(session, WT_ROW_UPDATE(page, rip));
- if (upd != NULL && WT_UPDATE_DELETED_ISSET(upd)) {
+ if (upd != NULL && upd->type == WT_UPDATE_DELETED) {
if (__wt_txn_visible_all(session, upd->txnid))
++cbt->page_deleted_count;
continue;
diff --git a/src/btree/bt_curprev.c b/src/btree/bt_curprev.c
index 4f0fa77d3e6..55b5095fe91 100644
--- a/src/btree/bt_curprev.c
+++ b/src/btree/bt_curprev.c
@@ -288,7 +288,7 @@ new_page: if (cbt->ins == NULL)
__cursor_set_recno(cbt, WT_INSERT_RECNO(cbt->ins));
if ((upd = __wt_txn_read(session, cbt->ins->upd)) == NULL)
continue;
- if (WT_UPDATE_DELETED_ISSET(upd)) {
+ if (upd->type == WT_UPDATE_DELETED) {
if (__wt_txn_visible_all(session, upd->txnid))
++cbt->page_deleted_count;
continue;
@@ -352,7 +352,7 @@ new_page: if (cbt->recno < cbt->ref->ref_recno)
upd = cbt->ins == NULL ?
NULL : __wt_txn_read(session, cbt->ins->upd);
if (upd != NULL) {
- if (WT_UPDATE_DELETED_ISSET(upd)) {
+ if (upd->type == WT_UPDATE_DELETED) {
if (__wt_txn_visible_all(session, upd->txnid))
++cbt->page_deleted_count;
continue;
@@ -482,7 +482,7 @@ __cursor_row_prev(WT_CURSOR_BTREE *cbt, bool newpage)
new_insert: if ((ins = cbt->ins) != NULL) {
if ((upd = __wt_txn_read(session, ins->upd)) == NULL)
continue;
- if (WT_UPDATE_DELETED_ISSET(upd)) {
+ if (upd->type == WT_UPDATE_DELETED) {
if (__wt_txn_visible_all(session, upd->txnid))
++cbt->page_deleted_count;
continue;
@@ -517,7 +517,7 @@ new_insert: if ((ins = cbt->ins) != NULL) {
cbt->slot = cbt->row_iteration_slot / 2 - 1;
rip = &page->pg_row[cbt->slot];
upd = __wt_txn_read(session, WT_ROW_UPDATE(page, rip));
- if (upd != NULL && WT_UPDATE_DELETED_ISSET(upd)) {
+ if (upd != NULL && upd->type == WT_UPDATE_DELETED) {
if (__wt_txn_visible_all(session, upd->txnid))
++cbt->page_deleted_count;
continue;
diff --git a/src/btree/bt_cursor.c b/src/btree/bt_cursor.c
index 664545ee3a0..7e415150cc5 100644
--- a/src/btree/bt_cursor.c
+++ b/src/btree/bt_cursor.c
@@ -224,7 +224,7 @@ __wt_cursor_valid(WT_CURSOR_BTREE *cbt, WT_UPDATE **updp)
*/
if (cbt->ins != NULL &&
(upd = __wt_txn_read(session, cbt->ins->upd)) != NULL) {
- if (WT_UPDATE_DELETED_ISSET(upd))
+ if (upd->type == WT_UPDATE_DELETED)
return (false);
if (updp != NULL)
*updp = upd;
@@ -297,7 +297,7 @@ __wt_cursor_valid(WT_CURSOR_BTREE *cbt, WT_UPDATE **updp)
page->modify->mod_row_update != NULL &&
(upd = __wt_txn_read(session,
page->modify->mod_row_update[cbt->slot])) != NULL) {
- if (WT_UPDATE_DELETED_ISSET(upd))
+ if (upd->type == WT_UPDATE_DELETED)
return (false);
if (updp != NULL)
*updp = upd;
@@ -342,11 +342,11 @@ __cursor_row_search(
* Column-store delete, insert, and update from an application cursor.
*/
static inline int
-__cursor_col_modify(WT_SESSION_IMPL *session,
- WT_CURSOR_BTREE *cbt, bool is_remove, bool is_reserve)
+__cursor_col_modify(
+ WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, u_int modify_type)
{
return (__wt_col_modify(session, cbt,
- cbt->iface.recno, &cbt->iface.value, NULL, is_remove, is_reserve));
+ cbt->iface.recno, &cbt->iface.value, NULL, modify_type));
}
/*
@@ -354,11 +354,11 @@ __cursor_col_modify(WT_SESSION_IMPL *session,
* Row-store insert, update and delete from an application cursor.
*/
static inline int
-__cursor_row_modify(WT_SESSION_IMPL *session,
- WT_CURSOR_BTREE *cbt, bool is_remove, bool is_reserve)
+__cursor_row_modify(
+ WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, u_int modify_type)
{
return (__wt_row_modify(session, cbt,
- &cbt->iface.key, &cbt->iface.value, NULL, is_remove, is_reserve));
+ &cbt->iface.key, &cbt->iface.value, NULL, modify_type));
}
/*
@@ -662,8 +662,8 @@ __wt_btcur_insert(WT_CURSOR_BTREE *cbt)
*/
cbt->compare = 0;
ret = btree->type == BTREE_ROW ?
- __cursor_row_modify(session, cbt, false, false) :
- __cursor_col_modify(session, cbt, false, false);
+ __cursor_row_modify(session, cbt, WT_UPDATE_STANDARD) :
+ __cursor_col_modify(session, cbt, WT_UPDATE_STANDARD);
if (ret == 0)
goto done;
@@ -700,7 +700,7 @@ retry: WT_ERR(__cursor_func_init(cbt, true));
cbt->compare == 0 && __wt_cursor_valid(cbt, NULL))
WT_ERR(WT_DUPLICATE_KEY);
- ret = __cursor_row_modify(session, cbt, false, false);
+ ret = __cursor_row_modify(session, cbt, WT_UPDATE_STANDARD);
} else {
/*
* Optionally insert a new record (ignoring the application's
@@ -723,7 +723,7 @@ retry: WT_ERR(__cursor_func_init(cbt, true));
(cbt->compare != 0 && __cursor_fix_implicit(btree, cbt))))
WT_ERR(WT_DUPLICATE_KEY);
- WT_ERR(__cursor_col_modify(session, cbt, false, false));
+ WT_ERR(__cursor_col_modify(session, cbt, WT_UPDATE_STANDARD));
if (append_key)
cbt->iface.recno = cbt->recno;
@@ -881,8 +881,8 @@ __wt_btcur_remove(WT_CURSOR_BTREE *cbt)
*/
cbt->compare = 0;
ret = btree->type == BTREE_ROW ?
- __cursor_row_modify(session, cbt, true, false) :
- __cursor_col_modify(session, cbt, true, false);
+ __cursor_row_modify(session, cbt, WT_UPDATE_DELETED) :
+ __cursor_col_modify(session, cbt, WT_UPDATE_DELETED);
if (ret == 0)
goto done;
@@ -921,7 +921,7 @@ retry: WT_ERR(__cursor_func_init(cbt, true));
if (cbt->compare != 0 || !__wt_cursor_valid(cbt, NULL))
WT_ERR(WT_NOTFOUND);
- ret = __cursor_row_modify(session, cbt, true, false);
+ ret = __cursor_row_modify(session, cbt, WT_UPDATE_DELETED);
} else {
WT_ERR(__cursor_col_search(session, cbt, NULL));
@@ -948,7 +948,8 @@ retry: WT_ERR(__cursor_func_init(cbt, true));
*/
cbt->recno = cursor->recno;
} else
- ret = __cursor_col_modify(session, cbt, true, false);
+ ret = __cursor_col_modify(
+ session, cbt, WT_UPDATE_DELETED);
}
err: if (ret == WT_RESTART) {
@@ -986,7 +987,7 @@ done: /*
* Update a record in the tree.
*/
static int
-__btcur_update(WT_CURSOR_BTREE *cbt, bool is_reserve)
+__btcur_update(WT_CURSOR_BTREE *cbt, u_int modify_type)
{
WT_BTREE *btree;
WT_CURFILE_STATE state;
@@ -998,15 +999,6 @@ __btcur_update(WT_CURSOR_BTREE *cbt, bool is_reserve)
cursor = &cbt->iface;
session = (WT_SESSION_IMPL *)cursor->session;
- WT_STAT_CONN_INCR(session, cursor_update);
- WT_STAT_DATA_INCR(session, cursor_update);
- WT_STAT_DATA_INCRV(session, cursor_update_bytes, cursor->value.size);
-
- if (btree->type == BTREE_ROW)
- WT_RET(__cursor_size_chk(session, &cursor->key));
- if (!is_reserve)
- WT_RET(__cursor_size_chk(session, &cursor->value));
-
/* It's no longer possible to bulk-load into the tree. */
__cursor_disable_bulk(session, btree);
@@ -1030,8 +1022,8 @@ __btcur_update(WT_CURSOR_BTREE *cbt, bool is_reserve)
*/
cbt->compare = 0;
ret = btree->type == BTREE_ROW ?
- __cursor_row_modify(session, cbt, false, is_reserve) :
- __cursor_col_modify(session, cbt, false, is_reserve);
+ __cursor_row_modify(session, cbt, modify_type) :
+ __cursor_col_modify(session, cbt, modify_type);
if (ret == 0)
goto done;
@@ -1069,7 +1061,7 @@ retry: WT_ERR(__cursor_func_init(cbt, true));
if (cbt->compare != 0 || !__wt_cursor_valid(cbt, NULL))
WT_ERR(WT_NOTFOUND);
}
- ret = __cursor_row_modify(session, cbt, false, is_reserve);
+ ret = __cursor_row_modify(session, cbt, modify_type);
} else {
WT_ERR(__cursor_col_search(session, cbt, NULL));
@@ -1088,7 +1080,7 @@ retry: WT_ERR(__cursor_func_init(cbt, true));
!__cursor_fix_implicit(btree, cbt))
WT_ERR(WT_NOTFOUND);
}
- ret = __cursor_col_modify(session, cbt, false, is_reserve);
+ ret = __cursor_col_modify(session, cbt, modify_type);
}
err: if (ret == WT_RESTART) {
@@ -1106,7 +1098,7 @@ err: if (ret == WT_RESTART) {
* pointer to the modify function's allocated update structure.
*/
done: if (ret == 0) {
- if (is_reserve) {
+ if (modify_type == WT_UPDATE_RESERVED) {
F_CLR(cursor, WT_CURSTD_VALUE_SET);
WT_TRET(__wt_key_return(session, cbt));
} else
@@ -1131,14 +1123,19 @@ __wt_btcur_reserve(WT_CURSOR_BTREE *cbt)
{
WT_CURSOR *cursor;
WT_DECL_RET;
+ WT_SESSION_IMPL *session;
bool overwrite;
cursor = &cbt->iface;
+ session = (WT_SESSION_IMPL *)cursor->session;
+
+ WT_STAT_CONN_INCR(session, cursor_reserve);
+ WT_STAT_DATA_INCR(session, cursor_reserve);
/* WT_CURSOR.reserve is update-without-overwrite and a special value. */
overwrite = F_ISSET(cursor, WT_CURSTD_OVERWRITE);
F_CLR(cursor, WT_CURSTD_OVERWRITE);
- ret = __btcur_update(cbt, true);
+ ret = __btcur_update(cbt, WT_UPDATE_RESERVED);
if (overwrite)
F_SET(cursor, WT_CURSTD_OVERWRITE);
return (ret);
@@ -1151,7 +1148,23 @@ __wt_btcur_reserve(WT_CURSOR_BTREE *cbt)
int
__wt_btcur_update(WT_CURSOR_BTREE *cbt)
{
- return (__btcur_update(cbt, false));
+ WT_BTREE *btree;
+ WT_CURSOR *cursor;
+ WT_SESSION_IMPL *session;
+
+ btree = cbt->btree;
+ cursor = &cbt->iface;
+ session = (WT_SESSION_IMPL *)cursor->session;
+
+ WT_STAT_CONN_INCR(session, cursor_update);
+ WT_STAT_DATA_INCR(session, cursor_update);
+ WT_STAT_DATA_INCRV(session, cursor_update_bytes, cursor->value.size);
+
+ if (btree->type == BTREE_ROW)
+ WT_RET(__cursor_size_chk(session, &cursor->key));
+ WT_RET(__cursor_size_chk(session, &cursor->value));
+
+ return (__btcur_update(cbt, WT_UPDATE_STANDARD));
}
/*
@@ -1274,7 +1287,7 @@ __wt_btcur_equals(WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *equalp)
static int
__cursor_truncate(WT_SESSION_IMPL *session,
WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop,
- int (*rmfunc)(WT_SESSION_IMPL *, WT_CURSOR_BTREE *, bool, bool))
+ int (*rmfunc)(WT_SESSION_IMPL *, WT_CURSOR_BTREE *, u_int))
{
WT_DECL_RET;
@@ -1302,7 +1315,7 @@ retry: WT_RET(__wt_btcur_search(start));
F_MASK((WT_CURSOR *)start, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT);
for (;;) {
- if ((ret = rmfunc(session, start, true, false)) != 0)
+ if ((ret = rmfunc(session, start, WT_UPDATE_DELETED)) != 0)
break;
if (stop != NULL && __cursor_equals(start, stop))
@@ -1329,7 +1342,7 @@ retry: WT_RET(__wt_btcur_search(start));
static int
__cursor_truncate_fix(WT_SESSION_IMPL *session,
WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop,
- int (*rmfunc)(WT_SESSION_IMPL *, WT_CURSOR_BTREE *, bool, bool))
+ int (*rmfunc)(WT_SESSION_IMPL *, WT_CURSOR_BTREE *, u_int))
{
WT_DECL_RET;
const uint8_t *value;
@@ -1360,7 +1373,7 @@ retry: WT_RET(__wt_btcur_search(start));
for (;;) {
value = (const uint8_t *)start->iface.value.data;
if (*value != 0 &&
- (ret = rmfunc(session, start, true, false)) != 0)
+ (ret = rmfunc(session, start, WT_UPDATE_DELETED)) != 0)
break;
if (stop != NULL && __cursor_equals(start, stop))
diff --git a/src/btree/bt_debug.c b/src/btree/bt_debug.c
index 538c363a864..c3f98a98ec5 100644
--- a/src/btree/bt_debug.c
+++ b/src/btree/bt_debug.c
@@ -985,9 +985,9 @@ static int
__debug_update(WT_DBG *ds, WT_UPDATE *upd, bool hexbyte)
{
for (; upd != NULL; upd = upd->next)
- if (WT_UPDATE_DELETED_ISSET(upd))
+ if (upd->type == WT_UPDATE_DELETED)
WT_RET(ds->f(ds, "\tvalue {deleted}\n"));
- else if (WT_UPDATE_RESERVED_ISSET(upd))
+ else if (upd->type == WT_UPDATE_RESERVED)
WT_RET(ds->f(ds, "\tvalue {reserved}\n"));
else if (hexbyte) {
WT_RET(ds->f(ds, "\t{"));
diff --git a/src/btree/bt_delete.c b/src/btree/bt_delete.c
index 12c3b044fda..4a88b672d47 100644
--- a/src/btree/bt_delete.c
+++ b/src/btree/bt_delete.c
@@ -333,7 +333,7 @@ __wt_delete_page_instantiate(WT_SESSION_IMPL *session, WT_REF *ref)
*/
for (i = 0, size = 0; i < page->entries; ++i) {
WT_ERR(__wt_calloc_one(session, &upd));
- WT_UPDATE_DELETED_SET(upd);
+ upd->type = WT_UPDATE_DELETED;
if (page_del == NULL)
upd->txnid = WT_TXN_NONE; /* Globally visible */
diff --git a/src/btree/bt_read.c b/src/btree/bt_read.c
index 72a69e8591c..e6a0f53ab40 100644
--- a/src/btree/bt_read.c
+++ b/src/btree/bt_read.c
@@ -90,7 +90,8 @@ __col_instantiate(WT_SESSION_IMPL *session,
{
/* Search the page and add updates. */
WT_RET(__wt_col_search(session, recno, ref, cbt));
- WT_RET(__wt_col_modify(session, cbt, recno, NULL, upd, false, false));
+ WT_RET(__wt_col_modify(
+ session, cbt, recno, NULL, upd, WT_UPDATE_STANDARD));
return (0);
}
@@ -104,7 +105,8 @@ __row_instantiate(WT_SESSION_IMPL *session,
{
/* Search the page and add updates. */
WT_RET(__wt_row_search(session, key, ref, cbt, true));
- WT_RET(__wt_row_modify(session, cbt, key, NULL, upd, false, false));
+ WT_RET(__wt_row_modify(
+ session, cbt, key, NULL, upd, WT_UPDATE_STANDARD));
return (0);
}
@@ -127,7 +129,8 @@ __las_page_instantiate(WT_SESSION_IMPL *session,
WT_UPDATE *first_upd, *last_upd, *upd;
size_t incr, total_incr;
uint64_t current_recno, las_counter, las_txnid, recno, upd_txnid;
- uint32_t las_id, upd_size, session_flags;
+ uint32_t las_id, session_flags;
+ uint8_t upd_type;
int exact;
const uint8_t *p;
@@ -188,9 +191,10 @@ __las_page_instantiate(WT_SESSION_IMPL *session,
/* Allocate the WT_UPDATE structure. */
WT_ERR(cursor->get_value(
- cursor, &upd_txnid, &upd_size, las_value));
- WT_ERR(__wt_update_alloc(session, las_value,
- &upd, &incr, upd_size == WT_UPDATE_DELETED_VALUE, false));
+ cursor, &upd_txnid, &upd_type, las_value));
+ WT_ERR(__wt_update_alloc(session, las_value, &upd, &incr,
+ upd_type == WT_UPDATE_DELETED ?
+ WT_UPDATE_DELETED : WT_UPDATE_STANDARD));
total_incr += incr;
upd->txnid = upd_txnid;
diff --git a/src/btree/bt_split.c b/src/btree/bt_split.c
index 23210a556da..c2c56a18131 100644
--- a/src/btree/bt_split.c
+++ b/src/btree/bt_split.c
@@ -1424,8 +1424,8 @@ __split_multi_inmem(
WT_ERR(__wt_col_search(session, recno, ref, &cbt));
/* Apply the modification. */
- WT_ERR(__wt_col_modify(
- session, &cbt, recno, NULL, upd, false, false));
+ WT_ERR(__wt_col_modify(session,
+ &cbt, recno, NULL, upd, WT_UPDATE_STANDARD));
break;
case WT_PAGE_ROW_LEAF:
/* Build a key. */
@@ -1447,7 +1447,7 @@ __split_multi_inmem(
/* Apply the modification. */
WT_ERR(__wt_row_modify(
- session, &cbt, key, NULL, upd, false, false));
+ session, &cbt, key, NULL, upd, WT_UPDATE_STANDARD));
break;
WT_ILLEGAL_VALUE_ERR(session);
}
diff --git a/src/btree/bt_stat.c b/src/btree/bt_stat.c
index 2b9c9bef8a2..e3b9bbced48 100644
--- a/src/btree/bt_stat.c
+++ b/src/btree/bt_stat.c
@@ -178,9 +178,9 @@ __stat_page_col_var(
*/
WT_SKIP_FOREACH(ins, WT_COL_UPDATE(page, cip)) {
upd = ins->upd;
- if (WT_UPDATE_RESERVED_ISSET(upd))
+ if (upd->type == WT_UPDATE_RESERVED)
continue;
- if (WT_UPDATE_DELETED_ISSET(upd)) {
+ if (upd->type == WT_UPDATE_DELETED) {
if (!orig_deleted) {
++deleted_cnt;
--entry_cnt;
@@ -195,9 +195,9 @@ __stat_page_col_var(
/* Walk any append list. */
WT_SKIP_FOREACH(ins, WT_COL_APPEND(page)) {
- if (WT_UPDATE_RESERVED_ISSET(ins->upd))
+ if (ins->upd->type == WT_UPDATE_RESERVED)
continue;
- if (WT_UPDATE_DELETED_ISSET(ins->upd))
+ if (ins->upd->type == WT_UPDATE_DELETED)
++deleted_cnt;
else
++entry_cnt;
@@ -268,8 +268,8 @@ __stat_page_row_leaf(
* key on the page.
*/
WT_SKIP_FOREACH(ins, WT_ROW_INSERT_SMALLEST(page))
- if (!WT_UPDATE_DELETED_ISSET(ins->upd) &&
- !WT_UPDATE_RESERVED_ISSET(ins->upd))
+ if (ins->upd->type != WT_UPDATE_DELETED &&
+ ins->upd->type != WT_UPDATE_RESERVED)
++entry_cnt;
/*
@@ -279,8 +279,8 @@ __stat_page_row_leaf(
WT_ROW_FOREACH(page, rip, i) {
upd = WT_ROW_UPDATE(page, rip);
if (upd == NULL ||
- (!WT_UPDATE_DELETED_ISSET(upd) &&
- !WT_UPDATE_RESERVED_ISSET(upd)))
+ (upd->type != WT_UPDATE_DELETED &&
+ upd->type != WT_UPDATE_RESERVED))
++entry_cnt;
if (upd == NULL && (cell =
__wt_row_leaf_value_cell(page, rip, NULL)) != NULL &&
@@ -289,8 +289,8 @@ __stat_page_row_leaf(
/* Walk K/V pairs inserted after the on-page K/V pair. */
WT_SKIP_FOREACH(ins, WT_ROW_INSERT(page, rip))
- if (!WT_UPDATE_DELETED_ISSET(ins->upd) &&
- !WT_UPDATE_RESERVED_ISSET(ins->upd))
+ if (ins->upd->type != WT_UPDATE_DELETED &&
+ ins->upd->type != WT_UPDATE_RESERVED)
++entry_cnt;
}
diff --git a/src/btree/col_modify.c b/src/btree/col_modify.c
index b45f369f1c2..c256f03a612 100644
--- a/src/btree/col_modify.c
+++ b/src/btree/col_modify.c
@@ -17,8 +17,7 @@ static int __col_insert_alloc(
*/
int
__wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt,
- uint64_t recno, const WT_ITEM *value, WT_UPDATE *upd_arg,
- bool is_remove, bool is_reserve)
+ uint64_t recno, const WT_ITEM *value, WT_UPDATE *upd_arg, u_int modify_type)
{
static const WT_ITEM col_fix_remove = { "", 1, NULL, 0, 0 };
WT_BTREE *btree;
@@ -38,13 +37,15 @@ __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt,
upd = upd_arg;
append = logged = false;
- if (is_remove || is_reserve) {
+ if (modify_type == WT_UPDATE_DELETED ||
+ modify_type == WT_UPDATE_RESERVED) {
/*
* Fixed-size column-store doesn't have on-page deleted values,
* it's a nul byte.
*/
- if (is_remove && btree->type == BTREE_COL_FIX) {
- is_remove = false;
+ if (modify_type == WT_UPDATE_DELETED &&
+ btree->type == BTREE_COL_FIX) {
+ modify_type = WT_UPDATE_STANDARD;
value = &col_fix_remove;
}
} else {
@@ -89,7 +90,7 @@ __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt,
/* Allocate a WT_UPDATE structure and transaction ID. */
WT_ERR(__wt_update_alloc(session,
- value, &upd, &upd_size, is_remove, is_reserve));
+ value, &upd, &upd_size, modify_type));
WT_ERR(__wt_txn_modify(session, upd));
logged = true;
@@ -150,7 +151,7 @@ __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt,
if (upd_arg == NULL) {
WT_ERR(__wt_update_alloc(session,
- value, &upd, &upd_size, is_remove, is_reserve));
+ value, &upd, &upd_size, modify_type));
WT_ERR(__wt_txn_modify(session, upd));
logged = true;
@@ -195,7 +196,7 @@ __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt,
}
/* If the update was successful, add it to the in-memory log. */
- if (logged && !is_reserve)
+ if (logged && modify_type != WT_UPDATE_RESERVED)
WT_ERR(__wt_txn_log_op(session, cbt));
if (0) {
diff --git a/src/btree/row_modify.c b/src/btree/row_modify.c
index d3b087f92c6..2bf3c2f29bc 100644
--- a/src/btree/row_modify.c
+++ b/src/btree/row_modify.c
@@ -48,7 +48,7 @@ __wt_page_modify_alloc(WT_SESSION_IMPL *session, WT_PAGE *page)
int
__wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt,
const WT_ITEM *key, const WT_ITEM *value,
- WT_UPDATE *upd_arg, bool is_remove, bool is_reserve)
+ WT_UPDATE *upd_arg, u_int modify_type)
{
WT_DECL_RET;
WT_INSERT *ins;
@@ -97,7 +97,7 @@ __wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt,
/* Allocate a WT_UPDATE structure and transaction ID. */
WT_ERR(__wt_update_alloc(session,
- value, &upd, &upd_size, is_remove, is_reserve));
+ value, &upd, &upd_size, modify_type));
WT_ERR(__wt_txn_modify(session, upd));
logged = true;
@@ -168,7 +168,7 @@ __wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt,
if (upd_arg == NULL) {
WT_ERR(__wt_update_alloc(session,
- value, &upd, &upd_size, is_remove, is_reserve));
+ value, &upd, &upd_size, modify_type));
WT_ERR(__wt_txn_modify(session, upd));
logged = true;
@@ -207,7 +207,7 @@ __wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt,
&ins, ins_size, skipdepth));
}
- if (logged && !is_reserve)
+ if (logged && modify_type != WT_UPDATE_RESERVED)
WT_ERR(__wt_txn_log_op(session, cbt));
if (0) {
@@ -261,7 +261,7 @@ __wt_row_insert_alloc(WT_SESSION_IMPL *session,
*/
int
__wt_update_alloc(WT_SESSION_IMPL *session, const WT_ITEM *value,
- WT_UPDATE **updp, size_t *sizep, bool is_remove, bool is_reserve)
+ WT_UPDATE **updp, size_t *sizep, u_int modify_type)
{
WT_UPDATE *upd;
@@ -271,13 +271,10 @@ __wt_update_alloc(WT_SESSION_IMPL *session, const WT_ITEM *value,
* Allocate the WT_UPDATE structure and room for the value, then copy
* the value into place.
*/
- if (is_remove || is_reserve) {
+ if (modify_type == WT_UPDATE_DELETED ||
+ modify_type == WT_UPDATE_RESERVED)
WT_RET(__wt_calloc(session, 1, sizeof(WT_UPDATE), &upd));
- if (is_remove)
- WT_UPDATE_DELETED_SET(upd);
- if (is_reserve)
- WT_UPDATE_RESERVED_SET(upd);
- } else {
+ else {
WT_RET(__wt_calloc(
session, 1, sizeof(WT_UPDATE) + value->size, &upd));
if (value->size != 0) {
@@ -285,6 +282,7 @@ __wt_update_alloc(WT_SESSION_IMPL *session, const WT_ITEM *value,
memcpy(WT_UPDATE_DATA(upd), value->data, value->size);
}
}
+ upd->type = (uint8_t)modify_type;
*updp = upd;
*sizep = WT_UPDATE_MEMSIZE(upd);
diff --git a/src/cursor/cur_backup.c b/src/cursor/cur_backup.c
index a30cb6f0e17..60750b88900 100644
--- a/src/cursor/cur_backup.c
+++ b/src/cursor/cur_backup.c
@@ -119,6 +119,7 @@ __wt_curbackup_open(WT_SESSION_IMPL *session,
__wt_cursor_notsup, /* search */
__wt_cursor_search_near_notsup, /* search-near */
__wt_cursor_notsup, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__wt_cursor_notsup, /* update */
__wt_cursor_notsup, /* remove */
__wt_cursor_notsup, /* reserve */
diff --git a/src/cursor/cur_config.c b/src/cursor/cur_config.c
index a0b87b2b3c6..6c198315e33 100644
--- a/src/cursor/cur_config.c
+++ b/src/cursor/cur_config.c
@@ -39,6 +39,7 @@ __wt_curconfig_open(WT_SESSION_IMPL *session,
__wt_cursor_notsup, /* search */
__wt_cursor_search_near_notsup, /* search-near */
__wt_cursor_notsup, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__wt_cursor_notsup, /* update */
__wt_cursor_notsup, /* remove */
__wt_cursor_notsup, /* reserve */
diff --git a/src/cursor/cur_ds.c b/src/cursor/cur_ds.c
index bb7a7a9994a..10de133be75 100644
--- a/src/cursor/cur_ds.c
+++ b/src/cursor/cur_ds.c
@@ -458,6 +458,7 @@ __wt_curds_open(
__curds_search, /* search */
__curds_search_near, /* search-near */
__curds_insert, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__curds_update, /* update */
__curds_remove, /* remove */
__wt_cursor_notsup, /* reserve */
diff --git a/src/cursor/cur_dump.c b/src/cursor/cur_dump.c
index 73328da6246..3e90d321db6 100644
--- a/src/cursor/cur_dump.c
+++ b/src/cursor/cur_dump.c
@@ -369,6 +369,7 @@ __wt_curdump_create(WT_CURSOR *child, WT_CURSOR *owner, WT_CURSOR **cursorp)
__curdump_search, /* search */
__curdump_search_near, /* search-near */
__curdump_insert, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__curdump_update, /* update */
__curdump_remove, /* remove */
__wt_cursor_notsup, /* reserve */
diff --git a/src/cursor/cur_file.c b/src/cursor/cur_file.c
index f4d42802032..4469cac685d 100644
--- a/src/cursor/cur_file.c
+++ b/src/cursor/cur_file.c
@@ -352,6 +352,11 @@ __curfile_reserve(WT_CURSOR *cursor)
WT_ERR(__wt_btcur_reserve(cbt));
+ /*
+ * Reserve maintains a position and key, which doesn't match the library
+ * API, where reserve maintains a value. Fix the API by searching after
+ * each successful reserve operation.
+ */
WT_ASSERT(session,
F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT);
WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_VALUE_SET) == 0);
@@ -430,6 +435,7 @@ __curfile_create(WT_SESSION_IMPL *session,
__curfile_search, /* search */
__curfile_search_near, /* search-near */
__curfile_insert, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__curfile_update, /* update */
__curfile_remove, /* remove */
__curfile_reserve, /* reserve */
diff --git a/src/cursor/cur_index.c b/src/cursor/cur_index.c
index fcf00e4fa03..e8fcb1b2702 100644
--- a/src/cursor/cur_index.c
+++ b/src/cursor/cur_index.c
@@ -449,6 +449,7 @@ __wt_curindex_open(WT_SESSION_IMPL *session,
__curindex_search, /* search */
__curindex_search_near, /* search-near */
__wt_cursor_notsup, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__wt_cursor_notsup, /* update */
__wt_cursor_notsup, /* remove */
__wt_cursor_notsup, /* reserve */
diff --git a/src/cursor/cur_join.c b/src/cursor/cur_join.c
index cebf8a7fd6e..e4ccb90139e 100644
--- a/src/cursor/cur_join.c
+++ b/src/cursor/cur_join.c
@@ -591,6 +591,7 @@ __curjoin_entry_member(WT_SESSION_IMPL *session, WT_CURSOR_JOIN_ENTRY *entry,
__wt_cursor_notsup, /* search */
__wt_cursor_search_near_notsup, /* search-near */
__curjoin_extract_insert, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__wt_cursor_notsup, /* update */
__wt_cursor_notsup, /* remove */
__wt_cursor_notsup, /* reserve */
@@ -1293,6 +1294,7 @@ __wt_curjoin_open(WT_SESSION_IMPL *session,
__wt_cursor_notsup, /* search */
__wt_cursor_search_near_notsup, /* search-near */
__wt_cursor_notsup, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__wt_cursor_notsup, /* update */
__wt_cursor_notsup, /* remove */
__wt_cursor_notsup, /* reserve */
diff --git a/src/cursor/cur_log.c b/src/cursor/cur_log.c
index c8dc44bb392..38e9d4a1784 100644
--- a/src/cursor/cur_log.c
+++ b/src/cursor/cur_log.c
@@ -342,6 +342,7 @@ __wt_curlog_open(WT_SESSION_IMPL *session,
__curlog_search, /* search */
__wt_cursor_search_near_notsup, /* search-near */
__wt_cursor_notsup, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__wt_cursor_notsup, /* update */
__wt_cursor_notsup, /* remove */
__wt_cursor_notsup, /* reserve */
diff --git a/src/cursor/cur_metadata.c b/src/cursor/cur_metadata.c
index 9a38996d4ce..d9aeed1fccd 100644
--- a/src/cursor/cur_metadata.c
+++ b/src/cursor/cur_metadata.c
@@ -550,6 +550,7 @@ __wt_curmetadata_open(WT_SESSION_IMPL *session,
__curmetadata_search, /* search */
__curmetadata_search_near, /* search-near */
__curmetadata_insert, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__curmetadata_update, /* update */
__curmetadata_remove, /* remove */
__wt_cursor_notsup, /* reserve */
diff --git a/src/cursor/cur_stat.c b/src/cursor/cur_stat.c
index 0bfe5679677..a1ec1d75918 100644
--- a/src/cursor/cur_stat.c
+++ b/src/cursor/cur_stat.c
@@ -576,6 +576,7 @@ __wt_curstat_open(WT_SESSION_IMPL *session,
__curstat_search, /* search */
__wt_cursor_search_near_notsup, /* search-near */
__wt_cursor_notsup, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__wt_cursor_notsup, /* update */
__wt_cursor_notsup, /* remove */
__wt_cursor_notsup, /* reserve */
diff --git a/src/cursor/cur_std.c b/src/cursor/cur_std.c
index e42c5c7766e..91995ab0e0a 100644
--- a/src/cursor/cur_std.c
+++ b/src/cursor/cur_std.c
@@ -90,6 +90,19 @@ __wt_cursor_equals_notsup(WT_CURSOR *cursor, WT_CURSOR *other, int *equalp)
}
/*
+ * __wt_cursor_modify_notsup --
+ * Unsupported cursor modify.
+ */
+int
+__wt_cursor_modify_notsup(WT_CURSOR *cursor, WT_MODIFY *entries, int nentries)
+{
+ WT_UNUSED(entries);
+ WT_UNUSED(nentries);
+
+ return (__wt_cursor_notsup(cursor));
+}
+
+/*
* __wt_cursor_search_near_notsup --
* Unsupported cursor search-near.
*/
@@ -582,6 +595,100 @@ err: API_END(session, ret);
}
/*
+ * __cursor_modify --
+ * WT_CURSOR->modify default implementation.
+ */
+static int
+__cursor_modify(WT_CURSOR *cursor, WT_MODIFY *entries, int nentries)
+{
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+ WT_DECL_ITEM(ta);
+ WT_DECL_ITEM(tb);
+ WT_DECL_ITEM(tmp);
+ size_t len, size;
+ int i;
+
+ CURSOR_UPDATE_API_CALL(cursor, session, modify);
+ WT_ERR(__cursor_checkkey(cursor));
+
+ /* Check for a rational modify vector count. */
+ if (nentries <= 0)
+ WT_ERR_MSG(
+ session, EINVAL, "Illegal modify vector of %d", nentries);
+
+ WT_STAT_CONN_INCR(session, cursor_modify);
+ WT_STAT_DATA_INCR(session, cursor_modify);
+
+ /* Acquire position and value. */
+ WT_ERR(cursor->search(cursor));
+
+ /*
+ * Process the entries to figure out how large a buffer we need. This is
+ * a bit pessimistic because we're ignoring replacement bytes, but it's
+ * a simpler calculation.
+ */
+ for (size = cursor->value.size, i = 0; i < nentries; ++i) {
+ if (entries[i].offset >= size)
+ size = entries[i].offset;
+ size += entries[i].data.size;
+ }
+
+ /* Allocate a pair of buffers. */
+ WT_ERR(__wt_scr_alloc(session, size, &ta));
+ WT_ERR(__wt_scr_alloc(session, size, &tb));
+
+ /* Apply the change vector to the value. */
+ WT_ERR(__wt_buf_set(
+ session, ta, cursor->value.data, cursor->value.size));
+ for (i = 0; i < nentries; ++i) {
+ /* Take leading bytes from the original, plus any gap bytes. */
+ if (entries[i].offset >= ta->size) {
+ memcpy(tb->mem, ta->mem, ta->size);
+ if (entries[i].offset > ta->size)
+ memset((uint8_t *)tb->mem + ta->size,
+ '\0', entries[i].offset - ta->size);
+ } else
+ if (entries[i].offset > 0)
+ memcpy(tb->mem, ta->mem, entries[i].offset);
+ tb->size = entries[i].offset;
+
+ /* Take replacement bytes. */
+ if (entries[i].data.size > 0) {
+ memcpy((uint8_t *)tb->mem + tb->size,
+ entries[i].data.data, entries[i].data.size);
+ tb->size += entries[i].data.size;
+ }
+
+ /* Take trailing bytes from the original. */
+ len = entries[i].offset + entries[i].size;
+ if (ta->size > len) {
+ memcpy((uint8_t *)tb->mem + tb->size,
+ (uint8_t *)ta->mem + len, ta->size - len);
+ tb->size += ta->size - len;
+ }
+ WT_ASSERT(session, tb->size <= size);
+
+ tmp = ta;
+ ta = tb;
+ tb = tmp;
+ }
+
+ /* Set the cursor's value. */
+ ta->data = ta->mem;
+ cursor->set_value(cursor, ta);
+
+ /* We know both key and value are set, "overwrite" doesn't matter. */
+ ret = cursor->update(cursor);
+
+err: __wt_scr_free(session, &ta);
+ __wt_scr_free(session, &tb);
+
+ CURSOR_UPDATE_API_END(session, ret);
+ return (ret);
+}
+
+/*
* __wt_cursor_reconfigure --
* Set runtime-configurable settings.
*/
@@ -757,6 +864,14 @@ __wt_cursor_init(WT_CURSOR *cursor,
F_SET(cursor, WT_CURSTD_RAW);
/*
+ * WT_CURSOR.modify supported on 'u' value formats, but may have been
+ * already initialized.
+ */
+ if (WT_STREQ(cursor->value_format, "u") &&
+ cursor->modify == __wt_cursor_modify_notsup)
+ cursor->modify = __cursor_modify;
+
+ /*
* Cursors that are internal to some other cursor (such as file cursors
* inside a table cursor) should be closed after the containing cursor.
* Arrange for that to happen by putting internal cursors after their
diff --git a/src/cursor/cur_table.c b/src/cursor/cur_table.c
index 89c98986c0f..3959d58476b 100644
--- a/src/cursor/cur_table.c
+++ b/src/cursor/cur_table.c
@@ -91,6 +91,7 @@ __wt_apply_single_idx(WT_SESSION_IMPL *session, WT_INDEX *idx,
__wt_cursor_notsup, /* search */
__wt_cursor_search_near_notsup, /* search-near */
__curextract_insert, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__wt_cursor_notsup, /* update */
__wt_cursor_notsup, /* remove */
__wt_cursor_notsup, /* reserve */
@@ -949,6 +950,7 @@ __wt_curtable_open(WT_SESSION_IMPL *session,
__curtable_search, /* search */
__curtable_search_near, /* search-near */
__curtable_insert, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__curtable_update, /* update */
__curtable_remove, /* remove */
__curtable_reserve, /* reserve */
diff --git a/src/docs/Doxyfile b/src/docs/Doxyfile
index 3d8c46962f1..e7382e2bc5e 100644
--- a/src/docs/Doxyfile
+++ b/src/docs/Doxyfile
@@ -1582,6 +1582,7 @@ PREDEFINED = DOXYGEN \
__wt_file_system:=WT_FILE_SYSTEM \
__wt_item:=WT_ITEM \
__wt_lsn:=WT_LSN \
+ __wt_modify:=WT_MODIFY \
__wt_session:=WT_SESSION \
__wt_txn_notify:=WT_TXN_NOTIFY \
WT_HANDLE_CLOSED(x):=x \
diff --git a/src/include/btmem.h b/src/include/btmem.h
index 6755db81007..4e8d3c05d7d 100644
--- a/src/include/btmem.h
+++ b/src/include/btmem.h
@@ -208,7 +208,7 @@ struct __wt_ovfl_txnc {
*/
#define WT_LAS_FORMAT \
"key_format=" WT_UNCHECKED_STRING(IuQQu) \
- ",value_format=" WT_UNCHECKED_STRING(QIu)
+ ",value_format=" WT_UNCHECKED_STRING(QBu)
/*
* WT_PAGE_MODIFY --
@@ -809,11 +809,11 @@ struct __wt_row { /* On-page key, on-page cell, or off-page WT_IKEY */
* Walk the entries of an in-memory row-store leaf page.
*/
#define WT_ROW_FOREACH(page, rip, i) \
- for ((i) = (page)->entries, \
+ for ((i) = (page)->entries, \
(rip) = (page)->pg_row; (i) > 0; ++(rip), --(i))
#define WT_ROW_FOREACH_REVERSE(page, rip, i) \
- for ((i) = (page)->entries, \
- (rip) = (page)->pg_row + ((page)->entries - 1); \
+ for ((i) = (page)->entries, \
+ (rip) = (page)->pg_row + ((page)->entries - 1); \
(i) > 0; --(rip), --(i))
/*
@@ -861,7 +861,7 @@ struct __wt_col {
* Walk the entries of variable-length column-store leaf page.
*/
#define WT_COL_FOREACH(page, cip, i) \
- for ((i) = (page)->entries, \
+ for ((i) = (page)->entries, \
(cip) = (page)->pg_var; (i) > 0; ++(cip), --(i))
/*
@@ -908,23 +908,16 @@ struct __wt_ikey {
* list.
*/
WT_PACKED_STRUCT_BEGIN(__wt_update)
- uint64_t txnid; /* update transaction */
+ uint64_t txnid; /* transaction */
WT_UPDATE *next; /* forward-linked list */
- /*
- * Use the maximum size and maximum size-1 as is-deleted and is-reserved
- * flags (which means we can't store 4GB objects), instead of increasing
- * the size of this structure for a flag bit.
- */
-#define WT_UPDATE_DELETED_VALUE UINT32_MAX
-#define WT_UPDATE_DELETED_SET(u) ((u)->size = WT_UPDATE_DELETED_VALUE)
-#define WT_UPDATE_DELETED_ISSET(u) ((u)->size == WT_UPDATE_DELETED_VALUE)
+ uint32_t size; /* data length */
-#define WT_UPDATE_RESERVED_VALUE (UINT32_MAX - 1)
-#define WT_UPDATE_RESERVED_SET(u) ((u)->size = WT_UPDATE_RESERVED_VALUE)
-#define WT_UPDATE_RESERVED_ISSET(u) ((u)->size == WT_UPDATE_RESERVED_VALUE)
- uint32_t size; /* update length */
+#define WT_UPDATE_STANDARD 0
+#define WT_UPDATE_DELETED 1
+#define WT_UPDATE_RESERVED 2
+ uint8_t type; /* type (one byte to conserve memory) */
/* The untyped value immediately follows the WT_UPDATE structure. */
#define WT_UPDATE_DATA(upd) \
@@ -936,9 +929,13 @@ WT_PACKED_STRUCT_BEGIN(__wt_update)
* cache overhead calculation.
*/
#define WT_UPDATE_MEMSIZE(upd) \
- WT_ALIGN(sizeof(WT_UPDATE) + (WT_UPDATE_DELETED_ISSET(upd) || \
- WT_UPDATE_RESERVED_ISSET(upd) ? 0 : (upd)->size), 32)
+ WT_ALIGN(sizeof(WT_UPDATE) + (upd)->size, 32)
WT_PACKED_STRUCT_END
+/*
+ * WT_UPDATE_SIZE is the expected structure size -- we verify the build to
+ * ensure the compiler hasn't inserted padding.
+ */
+#define WT_UPDATE_SIZE 21
/*
* WT_INSERT --
diff --git a/src/include/cursor.h b/src/include/cursor.h
index b044329fbfe..8d2f2c80c2a 100644
--- a/src/include/cursor.h
+++ b/src/include/cursor.h
@@ -22,6 +22,7 @@
search, \
search_near, \
insert, \
+ modify, \
update, \
remove, \
reserve, \
@@ -44,6 +45,7 @@
search, \
search_near, \
insert, \
+ modify, \
update, \
remove, \
reserve, \
diff --git a/src/include/extern.h b/src/include/extern.h
index a3ce0f3746f..01c21b188c0 100644
--- a/src/include/extern.h
+++ b/src/include/extern.h
@@ -180,7 +180,7 @@ extern int __wt_verify_dsk(WT_SESSION_IMPL *session, const char *tag, WT_ITEM *b
extern int __wt_tree_walk(WT_SESSION_IMPL *session, WT_REF **refp, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_tree_walk_count(WT_SESSION_IMPL *session, WT_REF **refp, uint64_t *walkcntp, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_tree_walk_skip( WT_SESSION_IMPL *session, WT_REF **refp, uint64_t *skipleafcntp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
-extern int __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, uint64_t recno, const WT_ITEM *value, WT_UPDATE *upd_arg, bool is_remove, bool is_reserve) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, uint64_t recno, const WT_ITEM *value, WT_UPDATE *upd_arg, u_int modify_type) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_col_search(WT_SESSION_IMPL *session, uint64_t search_recno, WT_REF *leaf, WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_row_leaf_keys(WT_SESSION_IMPL *session, WT_PAGE *page) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_row_leaf_key_copy( WT_SESSION_IMPL *session, WT_PAGE *page, WT_ROW *rip, WT_ITEM *key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
@@ -189,9 +189,9 @@ extern int __wt_row_ikey_alloc(WT_SESSION_IMPL *session, uint32_t cell_offset, c
extern int __wt_row_ikey_incr(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t cell_offset, const void *key, size_t size, WT_REF *ref) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_row_ikey(WT_SESSION_IMPL *session, uint32_t cell_offset, const void *key, size_t size, WT_REF *ref) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_page_modify_alloc(WT_SESSION_IMPL *session, WT_PAGE *page) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
-extern int __wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, const WT_ITEM *key, const WT_ITEM *value, WT_UPDATE *upd_arg, bool is_remove, bool is_reserve) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, const WT_ITEM *key, const WT_ITEM *value, WT_UPDATE *upd_arg, u_int modify_type) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_row_insert_alloc(WT_SESSION_IMPL *session, const WT_ITEM *key, u_int skipdepth, WT_INSERT **insp, size_t *ins_sizep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
-extern int __wt_update_alloc(WT_SESSION_IMPL *session, const WT_ITEM *value, WT_UPDATE **updp, size_t *sizep, bool is_remove, bool is_reserve) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_update_alloc(WT_SESSION_IMPL *session, const WT_ITEM *value, WT_UPDATE **updp, size_t *sizep, u_int modify_type) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern WT_UPDATE *__wt_update_obsolete_check( WT_SESSION_IMPL *session, WT_PAGE *page, WT_UPDATE *upd);
extern void __wt_update_obsolete_free( WT_SESSION_IMPL *session, WT_PAGE *page, WT_UPDATE *upd);
extern int __wt_search_insert(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_INSERT_HEAD *ins_head, WT_ITEM *srch_key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
@@ -314,6 +314,7 @@ extern void __wt_cursor_set_key_notsup(WT_CURSOR *cursor, ...);
extern void __wt_cursor_set_value_notsup(WT_CURSOR *cursor, ...);
extern int __wt_cursor_compare_notsup(WT_CURSOR *a, WT_CURSOR *b, int *cmpp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_cursor_equals_notsup(WT_CURSOR *cursor, WT_CURSOR *other, int *equalp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+extern int __wt_cursor_modify_notsup(WT_CURSOR *cursor, WT_MODIFY *entries, int nentries) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_cursor_search_near_notsup(WT_CURSOR *cursor, int *exact) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_cursor_reconfigure_notsup(WT_CURSOR *cursor, const char *config) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern void __wt_cursor_set_notsup(WT_CURSOR *cursor);
diff --git a/src/include/log.h b/src/include/log.h
index f80514a3546..e7bc28cd220 100644
--- a/src/include/log.h
+++ b/src/include/log.h
@@ -130,7 +130,7 @@ union __wt_lsn {
#define WT_LOG_SLOT_FLAGS(state) ((state) & WT_LOG_SLOT_MASK_ON)
#define WT_LOG_SLOT_JOINED(state) (((state) & WT_LOG_SLOT_MASK_OFF) >> 32)
#define WT_LOG_SLOT_JOINED_BUFFERED(state) \
- (WT_LOG_SLOT_JOINED(state) & \
+ (WT_LOG_SLOT_JOINED(state) & \
(WT_LOG_SLOT_UNBUFFERED - 1))
#define WT_LOG_SLOT_JOIN_REL(j, r, s) (((j) << 32) + (r) + (s))
#define WT_LOG_SLOT_RELEASED(state) ((int64_t)(int32_t)(state))
diff --git a/src/include/lsm.h b/src/include/lsm.h
index 08313438eb8..f8d0f480cbb 100644
--- a/src/include/lsm.h
+++ b/src/include/lsm.h
@@ -240,11 +240,11 @@ struct __wt_lsm_tree {
* area, copying them into place when a statistics cursor is created.
*/
#define WT_LSM_TREE_STAT_INCR(session, fld) do { \
- if (WT_STAT_ENABLED(session)) \
+ if (WT_STAT_ENABLED(session)) \
++(fld); \
} while (0)
#define WT_LSM_TREE_STAT_INCRV(session, fld, v) do { \
- if (WT_STAT_ENABLED(session)) \
+ if (WT_STAT_ENABLED(session)) \
(fld) += (int64_t)(v); \
} while (0)
int64_t bloom_false_positive;
diff --git a/src/include/mutex.h b/src/include/mutex.h
index c0e25ebb295..00babd47fbf 100644
--- a/src/include/mutex.h
+++ b/src/include/mutex.h
@@ -66,8 +66,8 @@ struct __wt_spinlock {
WT_CACHE_LINE_PAD_BEGIN
#if SPINLOCK_TYPE == SPINLOCK_GCC
volatile int lock;
-#elif SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX ||\
- SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX_ADAPTIVE ||\
+#elif SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX || \
+ SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX_ADAPTIVE || \
SPINLOCK_TYPE == SPINLOCK_MSVC
wt_mutex_t lock;
#else
diff --git a/src/include/mutex.i b/src/include/mutex.i
index 44b8494cdbf..5b14bb24730 100644
--- a/src/include/mutex.i
+++ b/src/include/mutex.i
@@ -102,8 +102,8 @@ __wt_spin_unlock(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
__sync_lock_release(&t->lock);
}
-#elif SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX ||\
- SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX_ADAPTIVE
+#elif SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX || \
+ SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX_ADAPTIVE
/*
* __wt_spin_init --
@@ -142,8 +142,8 @@ __wt_spin_destroy(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
}
}
-#if SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX ||\
- SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX_ADAPTIVE
+#if SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX || \
+ SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX_ADAPTIVE
/*
* __wt_spin_trylock --
diff --git a/src/include/schema.h b/src/include/schema.h
index fa836084834..8b8ee5616d1 100644
--- a/src/include/schema.h
+++ b/src/include/schema.h
@@ -323,7 +323,7 @@ struct __wt_table {
F_SET(session, WT_SESSION_LOCKED_HANDLE_LIST_READ); \
} \
if (__handle_write_locked) { \
- __wt_writelock(session, &__conn->dhandle_lock); \
+ __wt_writelock(session, &__conn->dhandle_lock); \
F_SET(session, WT_SESSION_LOCKED_HANDLE_LIST_WRITE); \
} \
} while (0)
diff --git a/src/include/stat.h b/src/include/stat.h
index beb589dc0ef..fa62cf27693 100644
--- a/src/include/stat.h
+++ b/src/include/stat.h
@@ -374,9 +374,11 @@ struct __wt_connection_stats {
int64_t write_io;
int64_t cursor_create;
int64_t cursor_insert;
+ int64_t cursor_modify;
int64_t cursor_next;
int64_t cursor_prev;
int64_t cursor_remove;
+ int64_t cursor_reserve;
int64_t cursor_reset;
int64_t cursor_restart;
int64_t cursor_search;
@@ -609,9 +611,11 @@ struct __wt_dsrc_stats {
int64_t cursor_remove_bytes;
int64_t cursor_update_bytes;
int64_t cursor_insert;
+ int64_t cursor_modify;
int64_t cursor_next;
int64_t cursor_prev;
int64_t cursor_remove;
+ int64_t cursor_reserve;
int64_t cursor_reset;
int64_t cursor_restart;
int64_t cursor_search;
diff --git a/src/include/txn.i b/src/include/txn.i
index 4b6ba17853f..f7321af5b12 100644
--- a/src/include/txn.i
+++ b/src/include/txn.i
@@ -235,7 +235,7 @@ __wt_txn_read(WT_SESSION_IMPL *session, WT_UPDATE *upd)
{
/* Skip reserved place-holders, they're never visible. */
for (; upd != NULL; upd = upd->next)
- if (!WT_UPDATE_RESERVED_ISSET(upd) &&
+ if (upd->type != WT_UPDATE_RESERVED &&
__wt_txn_visible(session, upd->txnid))
break;
diff --git a/src/include/verify_build.h b/src/include/verify_build.h
index d2ccf206990..e93f5931c21 100644
--- a/src/include/verify_build.h
+++ b/src/include/verify_build.h
@@ -52,6 +52,7 @@ __wt_verify_build(void)
/* Check specific structures weren't padded. */
WT_SIZE_CHECK(WT_BLOCK_DESC, WT_BLOCK_DESC_SIZE);
WT_SIZE_CHECK(WT_REF, WT_REF_SIZE);
+ WT_SIZE_CHECK(WT_UPDATE, WT_UPDATE_SIZE);
/* Check specific structures were padded. */
#define WT_PADDING_CHECK(s) \
diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in
index b93fbebef25..5e76b2915b1 100644
--- a/src/include/wiredtiger.in
+++ b/src/include/wiredtiger.in
@@ -49,12 +49,6 @@ extern "C" {
#define WT_ATTRIBUTE_LIBRARY_VISIBLE __attribute__((visibility("default")))
#endif
-#ifdef SWIG
-%{
-#include <wiredtiger.h>
-%}
-#endif
-
/*!
* @defgroup wt WiredTiger API
* The functions, handles and methods applications use to access and manage
@@ -84,6 +78,7 @@ struct __wt_extractor; typedef struct __wt_extractor WT_EXTRACTOR;
struct __wt_file_handle; typedef struct __wt_file_handle WT_FILE_HANDLE;
struct __wt_file_system; typedef struct __wt_file_system WT_FILE_SYSTEM;
struct __wt_item; typedef struct __wt_item WT_ITEM;
+struct __wt_modify; typedef struct __wt_modify WT_MODIFY;
struct __wt_session; typedef struct __wt_session WT_SESSION;
#if defined(SWIGJAVA)
@@ -138,6 +133,43 @@ struct __wt_item {
};
/*!
+ * A set of modifications for a value, including a pointer to new data and a
+ * length, plus a target offset in the value and an optional length of data
+ * in the value to be replaced.
+ *
+ * WT_MODIFY structures do not need to be cleared before use.
+ */
+struct __wt_modify {
+ /*!
+ * New data. The size of the new data may be zero when no new data is
+ * provided.
+ */
+ WT_ITEM data;
+
+ /*!
+ * The zero-based byte offset in the value where the new data is placed.
+ *
+ * If the offset is past the end of the value, nul bytes are appended to
+ * the value up to the specified offset.
+ */
+ size_t offset;
+
+ /*!
+ * The number of bytes in the value to be replaced.
+ *
+ * If the size is zero, no bytes from the value are replaced and the new
+ * data is inserted.
+ *
+ * If the offset is past the end of the value, the size is ignored.
+ *
+ * If the offset plus the size overlaps the end of the previous value,
+ * bytes from the offset to the end of the value are replaced and any
+ * remaining new data is appended.
+ */
+ size_t size;
+};
+
+/*!
* The maximum packed size of a 64-bit integer. The ::wiredtiger_struct_pack
* function will pack single long integers into at most this many bytes.
*/
@@ -446,6 +478,38 @@ struct __wt_cursor {
int __F(insert)(WT_CURSOR *cursor);
/*!
+ * Modify an existing record.
+ *
+ * Both the key and value must be set and the record must already exist;
+ * the record will be updated.
+ *
+ * Modification structures are applied in order, and later modifications
+ * can update earlier modifications.
+ *
+ * The modify method is only supported on raw byte arrays accessed using
+ * a WT_ITEM structure, that is, a format type of \c u.
+ *
+ * @snippet ex_all.c Modify an existing record
+ *
+ * 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.
+ *
+ * The maximum length of a single column stored in a table is not fixed
+ * (as it partially depends on the underlying file configuration), but
+ * is always a small number of bytes less than 4GB.
+ *
+ * @param cursor the cursor handle
+ * @param entries an array of modification data structures
+ * @param nentries the number of modification data structures
+ * @errors
+ * In particular, if \c in_memory is configured for the database and
+ * the modify requires more than the configured cache size to complete,
+ * ::WT_CACHE_FULL is returned.
+ */
+ int __F(modify)(WT_CURSOR *cursor, WT_MODIFY *entries, int nentries);
+
+ /*!
* Update an existing record and optionally insert a record.
*
* If the cursor was configured with "overwrite=true" (the default),
@@ -474,7 +538,7 @@ struct __wt_cursor {
* @errors
* In particular, if \c overwrite=false is configured and no record with
* the specified key exists, ::WT_NOTFOUND is returned.
- * Also, if \c in_memory is configured for the database and the insert
+ * Also, if \c in_memory is configured for the database and the update
* requires more than the configured cache size to complete,
* ::WT_CACHE_FULL is returned.
*/
@@ -4614,292 +4678,296 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection);
#define WT_STAT_CONN_CURSOR_CREATE 1115
/*! cursor: cursor insert calls */
#define WT_STAT_CONN_CURSOR_INSERT 1116
+/*! cursor: cursor modify calls */
+#define WT_STAT_CONN_CURSOR_MODIFY 1117
/*! cursor: cursor next calls */
-#define WT_STAT_CONN_CURSOR_NEXT 1117
+#define WT_STAT_CONN_CURSOR_NEXT 1118
/*! cursor: cursor prev calls */
-#define WT_STAT_CONN_CURSOR_PREV 1118
+#define WT_STAT_CONN_CURSOR_PREV 1119
/*! cursor: cursor remove calls */
-#define WT_STAT_CONN_CURSOR_REMOVE 1119
+#define WT_STAT_CONN_CURSOR_REMOVE 1120
+/*! cursor: cursor reserve calls */
+#define WT_STAT_CONN_CURSOR_RESERVE 1121
/*! cursor: cursor reset calls */
-#define WT_STAT_CONN_CURSOR_RESET 1120
+#define WT_STAT_CONN_CURSOR_RESET 1122
/*! cursor: cursor restarted searches */
-#define WT_STAT_CONN_CURSOR_RESTART 1121
+#define WT_STAT_CONN_CURSOR_RESTART 1123
/*! cursor: cursor search calls */
-#define WT_STAT_CONN_CURSOR_SEARCH 1122
+#define WT_STAT_CONN_CURSOR_SEARCH 1124
/*! cursor: cursor search near calls */
-#define WT_STAT_CONN_CURSOR_SEARCH_NEAR 1123
+#define WT_STAT_CONN_CURSOR_SEARCH_NEAR 1125
/*! cursor: cursor update calls */
-#define WT_STAT_CONN_CURSOR_UPDATE 1124
+#define WT_STAT_CONN_CURSOR_UPDATE 1126
/*! cursor: truncate calls */
-#define WT_STAT_CONN_CURSOR_TRUNCATE 1125
+#define WT_STAT_CONN_CURSOR_TRUNCATE 1127
/*! data-handle: connection data handles currently active */
-#define WT_STAT_CONN_DH_CONN_HANDLE_COUNT 1126
+#define WT_STAT_CONN_DH_CONN_HANDLE_COUNT 1128
/*! data-handle: connection sweep candidate became referenced */
-#define WT_STAT_CONN_DH_SWEEP_REF 1127
+#define WT_STAT_CONN_DH_SWEEP_REF 1129
/*! data-handle: connection sweep dhandles closed */
-#define WT_STAT_CONN_DH_SWEEP_CLOSE 1128
+#define WT_STAT_CONN_DH_SWEEP_CLOSE 1130
/*! data-handle: connection sweep dhandles removed from hash list */
-#define WT_STAT_CONN_DH_SWEEP_REMOVE 1129
+#define WT_STAT_CONN_DH_SWEEP_REMOVE 1131
/*! data-handle: connection sweep time-of-death sets */
-#define WT_STAT_CONN_DH_SWEEP_TOD 1130
+#define WT_STAT_CONN_DH_SWEEP_TOD 1132
/*! data-handle: connection sweeps */
-#define WT_STAT_CONN_DH_SWEEPS 1131
+#define WT_STAT_CONN_DH_SWEEPS 1133
/*! data-handle: session dhandles swept */
-#define WT_STAT_CONN_DH_SESSION_HANDLES 1132
+#define WT_STAT_CONN_DH_SESSION_HANDLES 1134
/*! data-handle: session sweep attempts */
-#define WT_STAT_CONN_DH_SESSION_SWEEPS 1133
+#define WT_STAT_CONN_DH_SESSION_SWEEPS 1135
/*! lock: checkpoint lock acquisitions */
-#define WT_STAT_CONN_LOCK_CHECKPOINT_COUNT 1134
+#define WT_STAT_CONN_LOCK_CHECKPOINT_COUNT 1136
/*! lock: checkpoint lock application thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_APPLICATION 1135
+#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_APPLICATION 1137
/*! lock: checkpoint lock internal thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_INTERNAL 1136
+#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_INTERNAL 1138
/*! lock: handle-list lock eviction thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_HANDLE_LIST_WAIT_EVICTION 1137
+#define WT_STAT_CONN_LOCK_HANDLE_LIST_WAIT_EVICTION 1139
/*! lock: metadata lock acquisitions */
-#define WT_STAT_CONN_LOCK_METADATA_COUNT 1138
+#define WT_STAT_CONN_LOCK_METADATA_COUNT 1140
/*! lock: metadata lock application thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_METADATA_WAIT_APPLICATION 1139
+#define WT_STAT_CONN_LOCK_METADATA_WAIT_APPLICATION 1141
/*! lock: metadata lock internal thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_METADATA_WAIT_INTERNAL 1140
+#define WT_STAT_CONN_LOCK_METADATA_WAIT_INTERNAL 1142
/*! lock: schema lock acquisitions */
-#define WT_STAT_CONN_LOCK_SCHEMA_COUNT 1141
+#define WT_STAT_CONN_LOCK_SCHEMA_COUNT 1143
/*! lock: schema lock application thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_APPLICATION 1142
+#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_APPLICATION 1144
/*! lock: schema lock internal thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_INTERNAL 1143
+#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_INTERNAL 1145
/*! lock: table lock acquisitions */
-#define WT_STAT_CONN_LOCK_TABLE_COUNT 1144
+#define WT_STAT_CONN_LOCK_TABLE_COUNT 1146
/*!
* lock: table lock application thread time waiting for the table lock
* (usecs)
*/
-#define WT_STAT_CONN_LOCK_TABLE_WAIT_APPLICATION 1145
+#define WT_STAT_CONN_LOCK_TABLE_WAIT_APPLICATION 1147
/*!
* lock: table lock internal thread time waiting for the table lock
* (usecs)
*/
-#define WT_STAT_CONN_LOCK_TABLE_WAIT_INTERNAL 1146
+#define WT_STAT_CONN_LOCK_TABLE_WAIT_INTERNAL 1148
/*! log: busy returns attempting to switch slots */
-#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1147
+#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1149
/*! log: log bytes of payload data */
-#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1148
+#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1150
/*! log: log bytes written */
-#define WT_STAT_CONN_LOG_BYTES_WRITTEN 1149
+#define WT_STAT_CONN_LOG_BYTES_WRITTEN 1151
/*! log: log files manually zero-filled */
-#define WT_STAT_CONN_LOG_ZERO_FILLS 1150
+#define WT_STAT_CONN_LOG_ZERO_FILLS 1152
/*! log: log flush operations */
-#define WT_STAT_CONN_LOG_FLUSH 1151
+#define WT_STAT_CONN_LOG_FLUSH 1153
/*! log: log force write operations */
-#define WT_STAT_CONN_LOG_FORCE_WRITE 1152
+#define WT_STAT_CONN_LOG_FORCE_WRITE 1154
/*! log: log force write operations skipped */
-#define WT_STAT_CONN_LOG_FORCE_WRITE_SKIP 1153
+#define WT_STAT_CONN_LOG_FORCE_WRITE_SKIP 1155
/*! log: log records compressed */
-#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1154
+#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1156
/*! log: log records not compressed */
-#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1155
+#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1157
/*! log: log records too small to compress */
-#define WT_STAT_CONN_LOG_COMPRESS_SMALL 1156
+#define WT_STAT_CONN_LOG_COMPRESS_SMALL 1158
/*! log: log release advances write LSN */
-#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1157
+#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1159
/*! log: log scan operations */
-#define WT_STAT_CONN_LOG_SCANS 1158
+#define WT_STAT_CONN_LOG_SCANS 1160
/*! log: log scan records requiring two reads */
-#define WT_STAT_CONN_LOG_SCAN_REREADS 1159
+#define WT_STAT_CONN_LOG_SCAN_REREADS 1161
/*! log: log server thread advances write LSN */
-#define WT_STAT_CONN_LOG_WRITE_LSN 1160
+#define WT_STAT_CONN_LOG_WRITE_LSN 1162
/*! log: log server thread write LSN walk skipped */
-#define WT_STAT_CONN_LOG_WRITE_LSN_SKIP 1161
+#define WT_STAT_CONN_LOG_WRITE_LSN_SKIP 1163
/*! log: log sync operations */
-#define WT_STAT_CONN_LOG_SYNC 1162
+#define WT_STAT_CONN_LOG_SYNC 1164
/*! log: log sync time duration (usecs) */
-#define WT_STAT_CONN_LOG_SYNC_DURATION 1163
+#define WT_STAT_CONN_LOG_SYNC_DURATION 1165
/*! log: log sync_dir operations */
-#define WT_STAT_CONN_LOG_SYNC_DIR 1164
+#define WT_STAT_CONN_LOG_SYNC_DIR 1166
/*! log: log sync_dir time duration (usecs) */
-#define WT_STAT_CONN_LOG_SYNC_DIR_DURATION 1165
+#define WT_STAT_CONN_LOG_SYNC_DIR_DURATION 1167
/*! log: log write operations */
-#define WT_STAT_CONN_LOG_WRITES 1166
+#define WT_STAT_CONN_LOG_WRITES 1168
/*! log: logging bytes consolidated */
-#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1167
+#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1169
/*! log: maximum log file size */
-#define WT_STAT_CONN_LOG_MAX_FILESIZE 1168
+#define WT_STAT_CONN_LOG_MAX_FILESIZE 1170
/*! log: number of pre-allocated log files to create */
-#define WT_STAT_CONN_LOG_PREALLOC_MAX 1169
+#define WT_STAT_CONN_LOG_PREALLOC_MAX 1171
/*! log: pre-allocated log files not ready and missed */
-#define WT_STAT_CONN_LOG_PREALLOC_MISSED 1170
+#define WT_STAT_CONN_LOG_PREALLOC_MISSED 1172
/*! log: pre-allocated log files prepared */
-#define WT_STAT_CONN_LOG_PREALLOC_FILES 1171
+#define WT_STAT_CONN_LOG_PREALLOC_FILES 1173
/*! log: pre-allocated log files used */
-#define WT_STAT_CONN_LOG_PREALLOC_USED 1172
+#define WT_STAT_CONN_LOG_PREALLOC_USED 1174
/*! log: records processed by log scan */
-#define WT_STAT_CONN_LOG_SCAN_RECORDS 1173
+#define WT_STAT_CONN_LOG_SCAN_RECORDS 1175
/*! log: slot close lost race */
-#define WT_STAT_CONN_LOG_SLOT_CLOSE_RACE 1174
+#define WT_STAT_CONN_LOG_SLOT_CLOSE_RACE 1176
/*! log: slot close unbuffered waits */
-#define WT_STAT_CONN_LOG_SLOT_CLOSE_UNBUF 1175
+#define WT_STAT_CONN_LOG_SLOT_CLOSE_UNBUF 1177
/*! log: slot closures */
-#define WT_STAT_CONN_LOG_SLOT_CLOSES 1176
+#define WT_STAT_CONN_LOG_SLOT_CLOSES 1178
/*! log: slot join atomic update races */
-#define WT_STAT_CONN_LOG_SLOT_RACES 1177
+#define WT_STAT_CONN_LOG_SLOT_RACES 1179
/*! log: slot join calls atomic updates raced */
-#define WT_STAT_CONN_LOG_SLOT_YIELD_RACE 1178
+#define WT_STAT_CONN_LOG_SLOT_YIELD_RACE 1180
/*! log: slot join calls did not yield */
-#define WT_STAT_CONN_LOG_SLOT_IMMEDIATE 1179
+#define WT_STAT_CONN_LOG_SLOT_IMMEDIATE 1181
/*! log: slot join calls found active slot closed */
-#define WT_STAT_CONN_LOG_SLOT_YIELD_CLOSE 1180
+#define WT_STAT_CONN_LOG_SLOT_YIELD_CLOSE 1182
/*! log: slot join calls slept */
-#define WT_STAT_CONN_LOG_SLOT_YIELD_SLEEP 1181
+#define WT_STAT_CONN_LOG_SLOT_YIELD_SLEEP 1183
/*! log: slot join calls yielded */
-#define WT_STAT_CONN_LOG_SLOT_YIELD 1182
+#define WT_STAT_CONN_LOG_SLOT_YIELD 1184
/*! log: slot join found active slot closed */
-#define WT_STAT_CONN_LOG_SLOT_ACTIVE_CLOSED 1183
+#define WT_STAT_CONN_LOG_SLOT_ACTIVE_CLOSED 1185
/*! log: slot joins yield time (usecs) */
-#define WT_STAT_CONN_LOG_SLOT_YIELD_DURATION 1184
+#define WT_STAT_CONN_LOG_SLOT_YIELD_DURATION 1186
/*! log: slot transitions unable to find free slot */
-#define WT_STAT_CONN_LOG_SLOT_NO_FREE_SLOTS 1185
+#define WT_STAT_CONN_LOG_SLOT_NO_FREE_SLOTS 1187
/*! log: slot unbuffered writes */
-#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1186
+#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1188
/*! log: total in-memory size of compressed records */
-#define WT_STAT_CONN_LOG_COMPRESS_MEM 1187
+#define WT_STAT_CONN_LOG_COMPRESS_MEM 1189
/*! log: total log buffer size */
-#define WT_STAT_CONN_LOG_BUFFER_SIZE 1188
+#define WT_STAT_CONN_LOG_BUFFER_SIZE 1190
/*! log: total size of compressed records */
-#define WT_STAT_CONN_LOG_COMPRESS_LEN 1189
+#define WT_STAT_CONN_LOG_COMPRESS_LEN 1191
/*! log: written slots coalesced */
-#define WT_STAT_CONN_LOG_SLOT_COALESCED 1190
+#define WT_STAT_CONN_LOG_SLOT_COALESCED 1192
/*! log: yields waiting for previous log file close */
-#define WT_STAT_CONN_LOG_CLOSE_YIELDS 1191
+#define WT_STAT_CONN_LOG_CLOSE_YIELDS 1193
/*! reconciliation: fast-path pages deleted */
-#define WT_STAT_CONN_REC_PAGE_DELETE_FAST 1192
+#define WT_STAT_CONN_REC_PAGE_DELETE_FAST 1194
/*! reconciliation: page reconciliation calls */
-#define WT_STAT_CONN_REC_PAGES 1193
+#define WT_STAT_CONN_REC_PAGES 1195
/*! reconciliation: page reconciliation calls for eviction */
-#define WT_STAT_CONN_REC_PAGES_EVICTION 1194
+#define WT_STAT_CONN_REC_PAGES_EVICTION 1196
/*! reconciliation: pages deleted */
-#define WT_STAT_CONN_REC_PAGE_DELETE 1195
+#define WT_STAT_CONN_REC_PAGE_DELETE 1197
/*! reconciliation: split bytes currently awaiting free */
-#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1196
+#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1198
/*! reconciliation: split objects currently awaiting free */
-#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1197
+#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1199
/*! session: open cursor count */
-#define WT_STAT_CONN_SESSION_CURSOR_OPEN 1198
+#define WT_STAT_CONN_SESSION_CURSOR_OPEN 1200
/*! session: open session count */
-#define WT_STAT_CONN_SESSION_OPEN 1199
+#define WT_STAT_CONN_SESSION_OPEN 1201
/*! session: table alter failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_ALTER_FAIL 1200
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_FAIL 1202
/*! session: table alter successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_ALTER_SUCCESS 1201
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_SUCCESS 1203
/*! session: table alter unchanged and skipped */
-#define WT_STAT_CONN_SESSION_TABLE_ALTER_SKIP 1202
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_SKIP 1204
/*! session: table compact failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL 1203
+#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL 1205
/*! session: table compact successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SUCCESS 1204
+#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SUCCESS 1206
/*! session: table create failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_CREATE_FAIL 1205
+#define WT_STAT_CONN_SESSION_TABLE_CREATE_FAIL 1207
/*! session: table create successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_CREATE_SUCCESS 1206
+#define WT_STAT_CONN_SESSION_TABLE_CREATE_SUCCESS 1208
/*! session: table drop failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_DROP_FAIL 1207
+#define WT_STAT_CONN_SESSION_TABLE_DROP_FAIL 1209
/*! session: table drop successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_DROP_SUCCESS 1208
+#define WT_STAT_CONN_SESSION_TABLE_DROP_SUCCESS 1210
/*! session: table rebalance failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_FAIL 1209
+#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_FAIL 1211
/*! session: table rebalance successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_SUCCESS 1210
+#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_SUCCESS 1212
/*! session: table rename failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_RENAME_FAIL 1211
+#define WT_STAT_CONN_SESSION_TABLE_RENAME_FAIL 1213
/*! session: table rename successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_RENAME_SUCCESS 1212
+#define WT_STAT_CONN_SESSION_TABLE_RENAME_SUCCESS 1214
/*! session: table salvage failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_FAIL 1213
+#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_FAIL 1215
/*! session: table salvage successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_SUCCESS 1214
+#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_SUCCESS 1216
/*! session: table truncate failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_FAIL 1215
+#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_FAIL 1217
/*! session: table truncate successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_SUCCESS 1216
+#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_SUCCESS 1218
/*! session: table verify failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_VERIFY_FAIL 1217
+#define WT_STAT_CONN_SESSION_TABLE_VERIFY_FAIL 1219
/*! session: table verify successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_VERIFY_SUCCESS 1218
+#define WT_STAT_CONN_SESSION_TABLE_VERIFY_SUCCESS 1220
/*! thread-state: active filesystem fsync calls */
-#define WT_STAT_CONN_THREAD_FSYNC_ACTIVE 1219
+#define WT_STAT_CONN_THREAD_FSYNC_ACTIVE 1221
/*! thread-state: active filesystem read calls */
-#define WT_STAT_CONN_THREAD_READ_ACTIVE 1220
+#define WT_STAT_CONN_THREAD_READ_ACTIVE 1222
/*! thread-state: active filesystem write calls */
-#define WT_STAT_CONN_THREAD_WRITE_ACTIVE 1221
+#define WT_STAT_CONN_THREAD_WRITE_ACTIVE 1223
/*! thread-yield: application thread time evicting (usecs) */
-#define WT_STAT_CONN_APPLICATION_EVICT_TIME 1222
+#define WT_STAT_CONN_APPLICATION_EVICT_TIME 1224
/*! thread-yield: application thread time waiting for cache (usecs) */
-#define WT_STAT_CONN_APPLICATION_CACHE_TIME 1223
+#define WT_STAT_CONN_APPLICATION_CACHE_TIME 1225
/*! thread-yield: page acquire busy blocked */
-#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1224
+#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1226
/*! thread-yield: page acquire eviction blocked */
-#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1225
+#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1227
/*! thread-yield: page acquire locked blocked */
-#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1226
+#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1228
/*! thread-yield: page acquire read blocked */
-#define WT_STAT_CONN_PAGE_READ_BLOCKED 1227
+#define WT_STAT_CONN_PAGE_READ_BLOCKED 1229
/*! thread-yield: page acquire time sleeping (usecs) */
-#define WT_STAT_CONN_PAGE_SLEEP 1228
+#define WT_STAT_CONN_PAGE_SLEEP 1230
/*! transaction: number of named snapshots created */
-#define WT_STAT_CONN_TXN_SNAPSHOTS_CREATED 1229
+#define WT_STAT_CONN_TXN_SNAPSHOTS_CREATED 1231
/*! transaction: number of named snapshots dropped */
-#define WT_STAT_CONN_TXN_SNAPSHOTS_DROPPED 1230
+#define WT_STAT_CONN_TXN_SNAPSHOTS_DROPPED 1232
/*! transaction: transaction begins */
-#define WT_STAT_CONN_TXN_BEGIN 1231
+#define WT_STAT_CONN_TXN_BEGIN 1233
/*! transaction: transaction checkpoint currently running */
-#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1232
+#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1234
/*! transaction: transaction checkpoint generation */
-#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1233
+#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1235
/*! transaction: transaction checkpoint max time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1234
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1236
/*! transaction: transaction checkpoint min time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1235
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1237
/*! transaction: transaction checkpoint most recent time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1236
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1238
/*! transaction: transaction checkpoint scrub dirty target */
-#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TARGET 1237
+#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TARGET 1239
/*! transaction: transaction checkpoint scrub time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TIME 1238
+#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TIME 1240
/*! transaction: transaction checkpoint total time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1239
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1241
/*! transaction: transaction checkpoints */
-#define WT_STAT_CONN_TXN_CHECKPOINT 1240
+#define WT_STAT_CONN_TXN_CHECKPOINT 1242
/*!
* transaction: transaction checkpoints skipped because database was
* clean
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_SKIPPED 1241
+#define WT_STAT_CONN_TXN_CHECKPOINT_SKIPPED 1243
/*! transaction: transaction failures due to cache overflow */
-#define WT_STAT_CONN_TXN_FAIL_CACHE 1242
+#define WT_STAT_CONN_TXN_FAIL_CACHE 1244
/*!
* transaction: transaction fsync calls for checkpoint after allocating
* the transaction ID
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST 1243
+#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST 1245
/*!
* transaction: transaction fsync duration for checkpoint after
* allocating the transaction ID (usecs)
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST_DURATION 1244
+#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST_DURATION 1246
/*! transaction: transaction range of IDs currently pinned */
-#define WT_STAT_CONN_TXN_PINNED_RANGE 1245
+#define WT_STAT_CONN_TXN_PINNED_RANGE 1247
/*! transaction: transaction range of IDs currently pinned by a checkpoint */
-#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1246
+#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1248
/*!
* transaction: transaction range of IDs currently pinned by named
* snapshots
*/
-#define WT_STAT_CONN_TXN_PINNED_SNAPSHOT_RANGE 1247
+#define WT_STAT_CONN_TXN_PINNED_SNAPSHOT_RANGE 1249
/*! transaction: transaction sync calls */
-#define WT_STAT_CONN_TXN_SYNC 1248
+#define WT_STAT_CONN_TXN_SYNC 1250
/*! transaction: transactions committed */
-#define WT_STAT_CONN_TXN_COMMIT 1249
+#define WT_STAT_CONN_TXN_COMMIT 1251
/*! transaction: transactions rolled back */
-#define WT_STAT_CONN_TXN_ROLLBACK 1250
+#define WT_STAT_CONN_TXN_ROLLBACK 1252
/*!
* @}
@@ -5181,61 +5249,65 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection);
#define WT_STAT_DSRC_CURSOR_UPDATE_BYTES 2092
/*! cursor: insert calls */
#define WT_STAT_DSRC_CURSOR_INSERT 2093
+/*! cursor: modify calls */
+#define WT_STAT_DSRC_CURSOR_MODIFY 2094
/*! cursor: next calls */
-#define WT_STAT_DSRC_CURSOR_NEXT 2094
+#define WT_STAT_DSRC_CURSOR_NEXT 2095
/*! cursor: prev calls */
-#define WT_STAT_DSRC_CURSOR_PREV 2095
+#define WT_STAT_DSRC_CURSOR_PREV 2096
/*! cursor: remove calls */
-#define WT_STAT_DSRC_CURSOR_REMOVE 2096
+#define WT_STAT_DSRC_CURSOR_REMOVE 2097
+/*! cursor: reserve calls */
+#define WT_STAT_DSRC_CURSOR_RESERVE 2098
/*! cursor: reset calls */
-#define WT_STAT_DSRC_CURSOR_RESET 2097
+#define WT_STAT_DSRC_CURSOR_RESET 2099
/*! cursor: restarted searches */
-#define WT_STAT_DSRC_CURSOR_RESTART 2098
+#define WT_STAT_DSRC_CURSOR_RESTART 2100
/*! cursor: search calls */
-#define WT_STAT_DSRC_CURSOR_SEARCH 2099
+#define WT_STAT_DSRC_CURSOR_SEARCH 2101
/*! cursor: search near calls */
-#define WT_STAT_DSRC_CURSOR_SEARCH_NEAR 2100
+#define WT_STAT_DSRC_CURSOR_SEARCH_NEAR 2102
/*! cursor: truncate calls */
-#define WT_STAT_DSRC_CURSOR_TRUNCATE 2101
+#define WT_STAT_DSRC_CURSOR_TRUNCATE 2103
/*! cursor: update calls */
-#define WT_STAT_DSRC_CURSOR_UPDATE 2102
+#define WT_STAT_DSRC_CURSOR_UPDATE 2104
/*! reconciliation: dictionary matches */
-#define WT_STAT_DSRC_REC_DICTIONARY 2103
+#define WT_STAT_DSRC_REC_DICTIONARY 2105
/*! reconciliation: fast-path pages deleted */
-#define WT_STAT_DSRC_REC_PAGE_DELETE_FAST 2104
+#define WT_STAT_DSRC_REC_PAGE_DELETE_FAST 2106
/*!
* reconciliation: internal page key bytes discarded using suffix
* compression
*/
-#define WT_STAT_DSRC_REC_SUFFIX_COMPRESSION 2105
+#define WT_STAT_DSRC_REC_SUFFIX_COMPRESSION 2107
/*! reconciliation: internal page multi-block writes */
-#define WT_STAT_DSRC_REC_MULTIBLOCK_INTERNAL 2106
+#define WT_STAT_DSRC_REC_MULTIBLOCK_INTERNAL 2108
/*! reconciliation: internal-page overflow keys */
-#define WT_STAT_DSRC_REC_OVERFLOW_KEY_INTERNAL 2107
+#define WT_STAT_DSRC_REC_OVERFLOW_KEY_INTERNAL 2109
/*! reconciliation: leaf page key bytes discarded using prefix compression */
-#define WT_STAT_DSRC_REC_PREFIX_COMPRESSION 2108
+#define WT_STAT_DSRC_REC_PREFIX_COMPRESSION 2110
/*! reconciliation: leaf page multi-block writes */
-#define WT_STAT_DSRC_REC_MULTIBLOCK_LEAF 2109
+#define WT_STAT_DSRC_REC_MULTIBLOCK_LEAF 2111
/*! reconciliation: leaf-page overflow keys */
-#define WT_STAT_DSRC_REC_OVERFLOW_KEY_LEAF 2110
+#define WT_STAT_DSRC_REC_OVERFLOW_KEY_LEAF 2112
/*! reconciliation: maximum blocks required for a page */
-#define WT_STAT_DSRC_REC_MULTIBLOCK_MAX 2111
+#define WT_STAT_DSRC_REC_MULTIBLOCK_MAX 2113
/*! reconciliation: overflow values written */
-#define WT_STAT_DSRC_REC_OVERFLOW_VALUE 2112
+#define WT_STAT_DSRC_REC_OVERFLOW_VALUE 2114
/*! reconciliation: page checksum matches */
-#define WT_STAT_DSRC_REC_PAGE_MATCH 2113
+#define WT_STAT_DSRC_REC_PAGE_MATCH 2115
/*! reconciliation: page reconciliation calls */
-#define WT_STAT_DSRC_REC_PAGES 2114
+#define WT_STAT_DSRC_REC_PAGES 2116
/*! reconciliation: page reconciliation calls for eviction */
-#define WT_STAT_DSRC_REC_PAGES_EVICTION 2115
+#define WT_STAT_DSRC_REC_PAGES_EVICTION 2117
/*! reconciliation: pages deleted */
-#define WT_STAT_DSRC_REC_PAGE_DELETE 2116
+#define WT_STAT_DSRC_REC_PAGE_DELETE 2118
/*! session: object compaction */
-#define WT_STAT_DSRC_SESSION_COMPACT 2117
+#define WT_STAT_DSRC_SESSION_COMPACT 2119
/*! session: open cursor count */
-#define WT_STAT_DSRC_SESSION_CURSOR_OPEN 2118
+#define WT_STAT_DSRC_SESSION_CURSOR_OPEN 2120
/*! transaction: update conflicts */
-#define WT_STAT_DSRC_TXN_UPDATE_CONFLICT 2119
+#define WT_STAT_DSRC_TXN_UPDATE_CONFLICT 2121
/*!
* @}
diff --git a/src/lsm/lsm_cursor.c b/src/lsm/lsm_cursor.c
index 90750a27ab3..99920367600 100644
--- a/src/lsm/lsm_cursor.c
+++ b/src/lsm/lsm_cursor.c
@@ -1756,6 +1756,7 @@ __wt_clsm_open(WT_SESSION_IMPL *session,
__clsm_search, /* search */
__clsm_search_near, /* search-near */
__clsm_insert, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__clsm_update, /* update */
__clsm_remove, /* remove */
__clsm_reserve, /* reserve */
diff --git a/src/reconcile/rec_write.c b/src/reconcile/rec_write.c
index 52a279b8c96..8f7769766a9 100644
--- a/src/reconcile/rec_write.c
+++ b/src/reconcile/rec_write.c
@@ -1227,7 +1227,8 @@ __rec_txn_read(WT_SESSION_IMPL *session, WT_RECONCILE *r,
}
/* Reconciliation should never see a reserved update. */
- WT_ASSERT(session, *updp == NULL || !WT_UPDATE_RESERVED_ISSET(*updp));
+ WT_ASSERT(session,
+ *updp == NULL || (*updp)->type != WT_UPDATE_RESERVED);
/*
* If all of the updates were aborted, quit. This test is not strictly
@@ -1411,14 +1412,14 @@ __rec_txn_read(WT_SESSION_IMPL *session, WT_RECONCILE *r,
* place a deleted record at the end of the update list.
*/
if (vpack == NULL || vpack->type == WT_CELL_DEL)
- WT_RET(__wt_update_alloc(
- session, NULL, &append, &notused, true, false));
+ WT_RET(__wt_update_alloc(session,
+ NULL, &append, &notused, WT_UPDATE_DELETED));
else {
WT_RET(__wt_scr_alloc(session, 0, &tmp));
if ((ret = __wt_page_cell_data_ref(
session, page, vpack, tmp)) == 0)
ret = __wt_update_alloc(session,
- tmp, &append, &notused, false, false);
+ tmp, &append, &notused, WT_UPDATE_STANDARD);
__wt_scr_free(session, &tmp);
WT_RET(ret);
}
@@ -3675,20 +3676,20 @@ __rec_update_las(WT_SESSION_IMPL *session,
* restored, obviously.
*/
do {
- if (WT_UPDATE_RESERVED_ISSET(upd))
+ if (upd->type == WT_UPDATE_RESERVED)
continue;
cursor->set_key(cursor, btree_id,
&las_addr, ++las_counter, list->onpage_txn, key);
- if (WT_UPDATE_DELETED_ISSET(upd))
+ if (upd->type == WT_UPDATE_DELETED)
las_value.size = 0;
else {
las_value.data = WT_UPDATE_DATA(upd);
las_value.size = upd->size;
}
cursor->set_value(
- cursor, upd->txnid, upd->size, &las_value);
+ cursor, upd->txnid, upd->type, &las_value);
WT_ERR(cursor->insert(cursor));
++insert_cnt;
@@ -4614,7 +4615,7 @@ record_loop: /*
update_no_copy = true; /* No data copy */
repeat_count = 1; /* Single record */
- deleted = WT_UPDATE_DELETED_ISSET(upd);
+ deleted = upd->type == WT_UPDATE_DELETED;
if (!deleted) {
data = WT_UPDATE_DATA(upd);
size = upd->size;
@@ -4849,7 +4850,7 @@ compare: /*
}
} else {
deleted = upd == NULL ||
- WT_UPDATE_DELETED_ISSET(upd);
+ upd->type == WT_UPDATE_DELETED;
if (!deleted) {
data = WT_UPDATE_DATA(upd);
size = upd->size;
@@ -5394,7 +5395,7 @@ __rec_row_leaf(WT_SESSION_IMPL *session,
__wt_ovfl_cache(session, page, rip, vpack));
/* If this key/value pair was deleted, we're done. */
- if (WT_UPDATE_DELETED_ISSET(upd)) {
+ if (upd->type == WT_UPDATE_DELETED) {
/*
* Overflow keys referencing discarded values
* are no longer useful, discard the backing
@@ -5604,7 +5605,7 @@ __rec_row_leaf_insert(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins)
for (; ins != NULL; ins = WT_SKIP_NEXT(ins)) {
/* Look for an update. */
WT_RET(__rec_txn_read(session, r, ins, NULL, NULL, &upd));
- if (upd == NULL || WT_UPDATE_DELETED_ISSET(upd))
+ if (upd == NULL || upd->type == WT_UPDATE_DELETED)
continue;
if (upd->size == 0) /* Build value cell. */
diff --git a/src/support/stat.c b/src/support/stat.c
index 8711e6b9bc1..bc40244f5e6 100644
--- a/src/support/stat.c
+++ b/src/support/stat.c
@@ -97,9 +97,11 @@ static const char * const __stats_dsrc_desc[] = {
"cursor: cursor-remove key bytes removed",
"cursor: cursor-update value bytes updated",
"cursor: insert calls",
+ "cursor: modify calls",
"cursor: next calls",
"cursor: prev calls",
"cursor: remove calls",
+ "cursor: reserve calls",
"cursor: reset calls",
"cursor: restarted searches",
"cursor: search calls",
@@ -259,9 +261,11 @@ __wt_stat_dsrc_clear_single(WT_DSRC_STATS *stats)
stats->cursor_remove_bytes = 0;
stats->cursor_update_bytes = 0;
stats->cursor_insert = 0;
+ stats->cursor_modify = 0;
stats->cursor_next = 0;
stats->cursor_prev = 0;
stats->cursor_remove = 0;
+ stats->cursor_reserve = 0;
stats->cursor_reset = 0;
stats->cursor_restart = 0;
stats->cursor_search = 0;
@@ -410,9 +414,11 @@ __wt_stat_dsrc_aggregate_single(
to->cursor_remove_bytes += from->cursor_remove_bytes;
to->cursor_update_bytes += from->cursor_update_bytes;
to->cursor_insert += from->cursor_insert;
+ to->cursor_modify += from->cursor_modify;
to->cursor_next += from->cursor_next;
to->cursor_prev += from->cursor_prev;
to->cursor_remove += from->cursor_remove;
+ to->cursor_reserve += from->cursor_reserve;
to->cursor_reset += from->cursor_reset;
to->cursor_restart += from->cursor_restart;
to->cursor_search += from->cursor_search;
@@ -588,9 +594,11 @@ __wt_stat_dsrc_aggregate(
to->cursor_remove_bytes += WT_STAT_READ(from, cursor_remove_bytes);
to->cursor_update_bytes += WT_STAT_READ(from, cursor_update_bytes);
to->cursor_insert += WT_STAT_READ(from, cursor_insert);
+ to->cursor_modify += WT_STAT_READ(from, cursor_modify);
to->cursor_next += WT_STAT_READ(from, cursor_next);
to->cursor_prev += WT_STAT_READ(from, cursor_prev);
to->cursor_remove += WT_STAT_READ(from, cursor_remove);
+ to->cursor_reserve += WT_STAT_READ(from, cursor_reserve);
to->cursor_reset += WT_STAT_READ(from, cursor_reset);
to->cursor_restart += WT_STAT_READ(from, cursor_restart);
to->cursor_search += WT_STAT_READ(from, cursor_search);
@@ -741,9 +749,11 @@ static const char * const __stats_connection_desc[] = {
"connection: total write I/Os",
"cursor: cursor create calls",
"cursor: cursor insert calls",
+ "cursor: cursor modify calls",
"cursor: cursor next calls",
"cursor: cursor prev calls",
"cursor: cursor remove calls",
+ "cursor: cursor reserve calls",
"cursor: cursor reset calls",
"cursor: cursor restarted searches",
"cursor: cursor search calls",
@@ -1034,9 +1044,11 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats)
stats->write_io = 0;
stats->cursor_create = 0;
stats->cursor_insert = 0;
+ stats->cursor_modify = 0;
stats->cursor_next = 0;
stats->cursor_prev = 0;
stats->cursor_remove = 0;
+ stats->cursor_reserve = 0;
stats->cursor_reset = 0;
stats->cursor_restart = 0;
stats->cursor_search = 0;
@@ -1347,9 +1359,11 @@ __wt_stat_connection_aggregate(
to->write_io += WT_STAT_READ(from, write_io);
to->cursor_create += WT_STAT_READ(from, cursor_create);
to->cursor_insert += WT_STAT_READ(from, cursor_insert);
+ to->cursor_modify += WT_STAT_READ(from, cursor_modify);
to->cursor_next += WT_STAT_READ(from, cursor_next);
to->cursor_prev += WT_STAT_READ(from, cursor_prev);
to->cursor_remove += WT_STAT_READ(from, cursor_remove);
+ to->cursor_reserve += WT_STAT_READ(from, cursor_reserve);
to->cursor_reset += WT_STAT_READ(from, cursor_reset);
to->cursor_restart += WT_STAT_READ(from, cursor_restart);
to->cursor_search += WT_STAT_READ(from, cursor_search);
diff --git a/src/txn/txn.c b/src/txn/txn.c
index ac4be37f855..d9edbb80564 100644
--- a/src/txn/txn.c
+++ b/src/txn/txn.c
@@ -600,7 +600,7 @@ __wt_txn_commit(WT_SESSION_IMPL *session, const char *cfg[])
* Switch reserved operations to abort to simplify
* obsolete update list truncation.
*/
- if (WT_UPDATE_RESERVED_ISSET(op->u.upd))
+ if (op->u.upd->type == WT_UPDATE_RESERVED)
op->u.upd->txnid = WT_TXN_ABORTED;
break;
case WT_TXN_OP_REF:
diff --git a/src/txn/txn_log.c b/src/txn/txn_log.c
index fae2027e1ec..74dc679a6ef 100644
--- a/src/txn/txn_log.c
+++ b/src/txn/txn_log.c
@@ -82,12 +82,12 @@ __txn_op_log(WT_SESSION_IMPL *session,
* or update, all of which require log records. We shouldn't ever log
* reserve operations.
*/
- WT_ASSERT(session, !WT_UPDATE_RESERVED_ISSET(upd));
+ WT_ASSERT(session, upd->type != WT_UPDATE_RESERVED);
if (cbt->btree->type == BTREE_ROW) {
#ifdef HAVE_DIAGNOSTIC
__txn_op_log_row_key_check(session, cbt);
#endif
- if (WT_UPDATE_DELETED_ISSET(upd))
+ if (upd->type == WT_UPDATE_DELETED)
WT_RET(__wt_logop_row_remove_pack(
session, logrec, op->fileid, &cursor->key));
else
@@ -97,7 +97,7 @@ __txn_op_log(WT_SESSION_IMPL *session,
recno = WT_INSERT_RECNO(cbt->ins);
WT_ASSERT(session, recno != WT_RECNO_OOB);
- if (WT_UPDATE_DELETED_ISSET(upd))
+ if (upd->type == WT_UPDATE_DELETED)
WT_RET(__wt_logop_col_remove_pack(
session, logrec, op->fileid, recno));
else