summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2014-03-26 15:27:47 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2014-03-26 15:27:47 +1100
commit1d33592856a3f475f46d1403f7593db59590a5b1 (patch)
tree703c64623db473fa48bed5c3303efd4f84d31d97 /src
parentaa78f5326f4e3d700efab28dde582d21c5dd2368 (diff)
downloadmongo-1d33592856a3f475f46d1403f7593db59590a5b1.tar.gz
Before merging extent lists, check if one is bigger than the other, and walk through the smaller one. This requires that we track sizes for the temporary avail list we build during checkpoints, otherwise we can't make the size tracking match up after the merge.
Diffstat (limited to 'src')
-rw-r--r--src/block/block_ckpt.c4
-rw-r--r--src/block/block_ext.c21
2 files changed, 23 insertions, 2 deletions
diff --git a/src/block/block_ckpt.c b/src/block/block_ckpt.c
index 690c6dffd34..38921a026cf 100644
--- a/src/block/block_ckpt.c
+++ b/src/block/block_ckpt.c
@@ -30,7 +30,7 @@ __wt_block_ckpt_init(
WT_RET(__wt_block_extlist_init(
session, &ci->discard, name, "discard", 0));
WT_RET(__wt_block_extlist_init(
- session, &ci->ckpt_avail, name, "ckpt_avail", 0));
+ session, &ci->ckpt_avail, name, "ckpt_avail", 1));
return (0);
}
@@ -366,7 +366,7 @@ __ckpt_process(
*/
__wt_block_extlist_free(session, &ci->ckpt_avail);
WT_RET(__wt_block_extlist_init(
- session, &ci->ckpt_avail, "live", "ckpt_avail", 0));
+ session, &ci->ckpt_avail, "live", "ckpt_avail", 1));
/*
* We've allocated our last page, update the checkpoint size. We need
diff --git a/src/block/block_ext.c b/src/block/block_ext.c
index 9b31cbf31a3..1ae0dbc2ce5 100644
--- a/src/block/block_ext.c
+++ b/src/block/block_ext.c
@@ -880,9 +880,30 @@ int
__wt_block_extlist_merge(WT_SESSION_IMPL *session, WT_EXTLIST *a, WT_EXTLIST *b)
{
WT_EXT *ext;
+ WT_EXTLIST tmp;
+ u_int i;
WT_VERBOSE_RET(session, block, "merging %s into %s", a->name, b->name);
+ /*
+ * Sometimes the list we are merging is much bigger than the other: if
+ * so, swap the lists around to reduce the amount of work we need to do
+ * during the merge. The size lists have to match as well, so
+ */
+ if (a->track_size == b->track_size && a->entries > b->entries) {
+ tmp = *a;
+ a->bytes = b->bytes;
+ b->bytes = tmp.bytes;
+ a->entries = b->entries;
+ b->entries = tmp.entries;
+ for (i = 0; i < WT_SKIP_MAXDEPTH; i++) {
+ a->off[i] = b->off[i];
+ b->off[i] = tmp.off[i];
+ a->sz[i] = b->sz[i];
+ b->sz[i] = tmp.sz[i];
+ }
+ }
+
WT_EXT_FOREACH(ext, a->off)
WT_RET(__block_merge(session, b, ext->off, ext->size));