summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Bostic <keith@wiredtiger.com>2014-05-12 13:04:53 -0400
committerKeith Bostic <keith@wiredtiger.com>2014-05-12 13:04:53 -0400
commit8e6243ba04baf0cca57217266ff0f921b6d4da55 (patch)
tree6710273fe943ae14bb79847ef216151924d80791
parenta8589b4039b0eee1ae4188dd5a950cc1d08c48be (diff)
downloadmongo-8e6243ba04baf0cca57217266ff0f921b6d4da55.tar.gz
Be a little more defensive: a reasonable compression function might not
be checking the target allocation size. If compression succeeds, but it doesn't gain us at least an allocation unit, don't compress the data.
-rw-r--r--src/btree/bt_io.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/src/btree/bt_io.c b/src/btree/bt_io.c
index 961b4251df2..1b75aa7b1ad 100644
--- a/src/btree/bt_io.c
+++ b/src/btree/bt_io.c
@@ -214,21 +214,26 @@ __wt_bt_write(WT_SESSION_IMPL *session, WT_ITEM *buf,
dst = (uint8_t *)tmp->mem + WT_BLOCK_COMPRESS_SKIP;
dst_len = len;
- /*
- * If compression fails, fallback to the original version. This
- * isn't unexpected: if compression doesn't work for some chunk
- * of bytes for some reason (noting there's likely additional
- * format/header information which compressed output requires),
- * it just means the uncompressed version is as good as it gets,
- * and that's what we use.
- */
compression_failed = 0;
WT_ERR(btree->compressor->compress(btree->compressor,
&session->iface,
src, src_len,
dst, dst_len,
&result_len, &compression_failed));
- if (compression_failed) {
+ result_len += WT_BLOCK_COMPRESS_SKIP;
+
+ /*
+ * If compression fails, or doesn't gain us at least one unit of
+ * allocation, fallback to the original version. This isn't
+ * unexpected: if compression doesn't work for some chunk of
+ * data for some reason (noting likely additional format/header
+ * information which compressed output requires), it just means
+ * the uncompressed version is as good as it gets, and that's
+ * what we use.
+ */
+ if (compression_failed ||
+ buf->size / btree->allocsize ==
+ result_len / btree->allocsize) {
ip = buf;
WT_STAT_FAST_DATA_INCR(session, compress_write_fail);
} else {
@@ -240,8 +245,7 @@ __wt_bt_write(WT_SESSION_IMPL *session, WT_ITEM *buf,
* size.
*/
memcpy(tmp->mem, buf->mem, WT_BLOCK_COMPRESS_SKIP);
- tmp->size =
- (uint32_t)result_len + WT_BLOCK_COMPRESS_SKIP;
+ tmp->size = result_len;
ip = tmp;
}
}