diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2014-03-26 15:27:47 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2014-03-26 15:27:47 +1100 |
commit | 1d33592856a3f475f46d1403f7593db59590a5b1 (patch) | |
tree | 703c64623db473fa48bed5c3303efd4f84d31d97 /src | |
parent | aa78f5326f4e3d700efab28dde582d21c5dd2368 (diff) | |
download | mongo-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.c | 4 | ||||
-rw-r--r-- | src/block/block_ext.c | 21 |
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)); |