summaryrefslogtreecommitdiff
path: root/src/btree/col_modify.c
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2013-10-15 16:31:34 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2013-10-15 16:31:34 +1100
commita0609b034d4776d57ec47b223e7e24319cefdc06 (patch)
treee146ab341992f1e81f6701b5196862fae85b2a09 /src/btree/col_modify.c
parent98c50e30f65e533a240a2813df2e6fd49a9ba76b (diff)
downloadmongo-a0609b034d4776d57ec47b223e7e24319cefdc06.tar.gz
Always set up next pointers before calling insert_serial. Never search inside the serial lock: if the configured insert isn't in the right place, restart the operation.
Follows on from the changes in #718
Diffstat (limited to 'src/btree/col_modify.c')
-rw-r--r--src/btree/col_modify.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/src/btree/col_modify.c b/src/btree/col_modify.c
index 046fb9d2157..5a61758d519 100644
--- a/src/btree/col_modify.c
+++ b/src/btree/col_modify.c
@@ -138,26 +138,34 @@ __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, int is_remove)
cbt->ins = ins;
/*
- * Point the new WT_INSERT item's skiplist references to the
- * next elements in the insert list (which might be complete
- * garbage, but we'll check inside the serialization function).
- * If we get it right (and we can mostly), the serialization
- * function lock acts as our memory barrier to flush these
- * writes before inserting them into the list.
+ * If there was no WT_INSERT_HEAD during the search, the
+ * cursor's information cannot be correct, search could not
+ * have initialized it.
+ *
+ * Otherwise, point the new WT_INSERT item's skiplist
+ * references to the next elements in the insert list (which we
+ * will check are still valid inside the serialization
+ * function). The serial mutex acts as our memory barrier to
+ * flush these writes before inserting them into the list.
*/
- for (i = 0; i < skipdepth && cbt->ins_stack[i] != NULL; i++)
- ins->next[i] = *cbt->ins_stack[i];
+ if (cbt->ins_stack[0] == NULL)
+ for (i = 0; i < skipdepth; i++) {
+ cbt->ins_stack[i] = &ins_head->head[i];
+ ins->next[i] = cbt->next_stack[i] = NULL;
+ }
+ else
+ for (i = 0; i < skipdepth; i++)
+ ins->next[i] = cbt->next_stack[i];
/* Append or insert the WT_INSERT structure. */
if (append)
WT_ERR(__wt_col_append_serial(
session, page,
- cbt->ins_head, cbt->ins_stack, cbt->next_stack,
+ cbt->ins_head, cbt->ins_stack,
&ins, ins_size, &cbt->recno, skipdepth));
else
WT_ERR(__wt_insert_serial(
- session, page,
- cbt->ins_head, cbt->ins_stack, cbt->next_stack,
+ session, page, cbt->ins_head, cbt->ins_stack,
&ins, ins_size, skipdepth));
}