summaryrefslogtreecommitdiff
path: root/src/btree/bt_split.c
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2015-03-09 17:47:27 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2015-03-09 17:47:27 +1100
commit3a3bda539cdd34428b7489fa0fa102ff0605e8d8 (patch)
treefc901ad7b45300181356b8305ecb02fff13f4bfc /src/btree/bt_split.c
parent89f45aafdff48bf7c8e191b788a144cab0b86122 (diff)
parent0afa07b0cd666adf7576901540a699b0bec396e3 (diff)
downloadmongo-3a3bda539cdd34428b7489fa0fa102ff0605e8d8.tar.gz
Merge branch 'develop' into mongodb-3.0
Conflicts: NEWS.MONGODB
Diffstat (limited to 'src/btree/bt_split.c')
-rw-r--r--src/btree/bt_split.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/src/btree/bt_split.c b/src/btree/bt_split.c
index 6ebd4609efa..95fb9c68a86 100644
--- a/src/btree/bt_split.c
+++ b/src/btree/bt_split.c
@@ -281,8 +281,8 @@ __split_ref_deepen_move(WT_SESSION_IMPL *session,
if (parent->type == WT_PAGE_ROW_INT) {
if ((ikey = __wt_ref_key_instantiated(ref)) == NULL) {
__wt_ref_key(parent, ref, &key, &size);
- WT_RET(__wt_row_ikey(session, 0, key, size, &ikey));
- ref->key.ikey = ikey;
+ WT_RET(__wt_row_ikey(session, 0, key, size, ref));
+ ikey = ref->key.ikey;
} else {
WT_RET(__split_ovfl_key_cleanup(session, parent, ref));
*parent_decrp += sizeof(WT_IKEY) + ikey->size;
@@ -454,8 +454,7 @@ __split_deepen(WT_SESSION_IMPL *session, WT_PAGE *parent, uint32_t children)
ref->addr = NULL;
if (parent->type == WT_PAGE_ROW_INT) {
__wt_ref_key(parent, *parent_refp, &p, &size);
- WT_ERR(
- __wt_row_ikey(session, 0, p, size, &ref->key.ikey));
+ WT_ERR(__wt_row_ikey(session, 0, p, size, ref));
parent_incr += sizeof(WT_IKEY) + size;
} else
ref->key.recno = (*parent_refp)->key.recno;
@@ -468,7 +467,7 @@ __split_deepen(WT_SESSION_IMPL *session, WT_PAGE *parent, uint32_t children)
/* Mark it dirty. */
WT_ERR(__wt_page_modify_init(session, child));
- __wt_page_only_modify_set(session, child);
+ __wt_page_modify_set(session, child);
/*
* Once the split goes live, the newly created internal pages
@@ -761,8 +760,8 @@ __wt_multi_to_ref(WT_SESSION_IMPL *session,
case WT_PAGE_ROW_INT:
case WT_PAGE_ROW_LEAF:
ikey = multi->key.ikey;
- WT_RET(__wt_row_ikey(session, 0,
- WT_IKEY_DATA(ikey), ikey->size, &ref->key.ikey));
+ WT_RET(__wt_row_ikey(
+ session, 0, WT_IKEY_DATA(ikey), ikey->size, ref));
incr += sizeof(WT_IKEY) + ikey->size;
break;
default:
@@ -855,7 +854,8 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new,
for (i = 0, deleted_entries = 0; i < parent_entries; ++i) {
next_ref = pindex->index[i];
WT_ASSERT(session, next_ref->state != WT_REF_SPLIT);
- if (__wt_delete_page_skip(session, next_ref) &&
+ if (next_ref->state == WT_REF_DELETED &&
+ __wt_delete_page_skip(session, next_ref) &&
WT_ATOMIC_CAS4(next_ref->state,
WT_REF_DELETED, WT_REF_SPLIT))
deleted_entries++;
@@ -1139,15 +1139,23 @@ __wt_split_insert(WT_SESSION_IMPL *session, WT_REF *ref, int *splitp)
F_SET_ATOMIC(page, WT_PAGE_SPLIT_INSERT);
/*
- * The first page in the split is the current page, but we still need to
- * create a replacement WT_REF and make a copy of the key (the original
- * WT_REF is set to split-status and eventually freed).
- *
- * The new reference is visible to readers once the split completes.
+ * The first page in the split is the current page, but we still have
+ * to create a replacement WT_REF, the original WT_REF will be set to
+ * split status and eventually freed.
*/
WT_ERR(__wt_calloc_one(session, &split_ref[0]));
child = split_ref[0];
*child = *ref;
+
+ /*
+ * The new WT_REF is not quite identical: we have to instantiate a key,
+ * and the new reference is visible to readers once the split completes.
+ *
+ * The key-instantiation code checks for races, clear the key fields so
+ * we don't trigger them.
+ */
+ child->key.recno = 0;
+ child->key.ikey = NULL;
child->state = WT_REF_MEM;
/*
@@ -1167,8 +1175,7 @@ __wt_split_insert(WT_SESSION_IMPL *session, WT_REF *ref, int *splitp)
} else
WT_ERR(__wt_row_leaf_key(
session, page, &page->pg_row_d[0], key, 1));
- WT_ERR(__wt_row_ikey(
- session, 0, key->data, key->size, &child->key.ikey));
+ WT_ERR(__wt_row_ikey(session, 0, key->data, key->size, child));
parent_incr += sizeof(WT_REF) + sizeof(WT_IKEY) + key->size;
__wt_scr_free(session, &key);
@@ -1187,7 +1194,7 @@ __wt_split_insert(WT_SESSION_IMPL *session, WT_REF *ref, int *splitp)
child->state = WT_REF_MEM;
WT_ERR(__wt_row_ikey(session, 0,
WT_INSERT_KEY(moved_ins), WT_INSERT_KEY_SIZE(moved_ins),
- &child->key.ikey));
+ child));
parent_incr +=
sizeof(WT_REF) + sizeof(WT_IKEY) + WT_INSERT_KEY_SIZE(moved_ins);
@@ -1203,7 +1210,7 @@ __wt_split_insert(WT_SESSION_IMPL *session, WT_REF *ref, int *splitp)
/* The new page is dirty by definition. */
WT_ERR(__wt_page_modify_init(session, right));
- __wt_page_only_modify_set(session, right);
+ __wt_page_modify_set(session, right);
/*
* We modified the page above, which will have set the first dirty