summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Gorrod <alexg@wiredtiger.com>2014-03-26 20:15:36 +1100
committerAlex Gorrod <alexg@wiredtiger.com>2014-03-26 20:15:36 +1100
commitc4edda12cd11e5d2430059b7bf6cfdb1f0b46f96 (patch)
tree460be2f043048ef5411ebd9a8c11d07964b9e469
parentaa78f5326f4e3d700efab28dde582d21c5dd2368 (diff)
parentbae3b4b871c67908c1d1ae6a9e93c20c053ad859 (diff)
downloadmongo-c4edda12cd11e5d2430059b7bf6cfdb1f0b46f96.tar.gz
Merge pull request #929 from wiredtiger/extlist-merge-swap
Make extent list management more efficient during checkpoints
-rw-r--r--src/block/block_ckpt.c4
-rw-r--r--src/block/block_ext.c22
2 files changed, 24 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..583b0b59961 100644
--- a/src/block/block_ext.c
+++ b/src/block/block_ext.c
@@ -880,9 +880,31 @@ 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 this is
+ * only possible if both lists are tracking sizes, or neither are.
+ */
+ 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));