diff options
author | Alex Gorrod <alexander.gorrod@mongodb.com> | 2017-05-25 10:50:53 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-25 10:50:53 -0400 |
commit | 4641a4586fd18925b3e91881b7c5fd7a203c337b (patch) | |
tree | dda590b7d49981bc868d990384b3cfb756a33c12 /src | |
parent | f7ac27044ef7a0332c68be16d51ad25077d4f8b2 (diff) | |
download | mongo-4641a4586fd18925b3e91881b7c5fd7a203c337b.tar.gz |
WT-2972 Add interface allowing partial updates to existing values (#3435)
Diffstat (limited to 'src')
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, ¬used, true, false)); + WT_RET(__wt_update_alloc(session, + NULL, &append, ¬used, 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, ¬used, false, false); + tmp, &append, ¬used, 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 |