diff options
author | Alex Gorrod <alexg@wiredtiger.com> | 2014-03-26 20:15:36 +1100 |
---|---|---|
committer | Alex Gorrod <alexg@wiredtiger.com> | 2014-03-26 20:15:36 +1100 |
commit | c4edda12cd11e5d2430059b7bf6cfdb1f0b46f96 (patch) | |
tree | 460be2f043048ef5411ebd9a8c11d07964b9e469 | |
parent | aa78f5326f4e3d700efab28dde582d21c5dd2368 (diff) | |
parent | bae3b4b871c67908c1d1ae6a9e93c20c053ad859 (diff) | |
download | mongo-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.c | 4 | ||||
-rw-r--r-- | src/block/block_ext.c | 22 |
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)); |