summaryrefslogtreecommitdiff
path: root/ext/compressors
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2015-03-25 12:13:08 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2015-03-25 12:13:08 +1100
commit4c0881afeb6713ef7ae9ea2b8f61811b0fecd192 (patch)
tree16f02247c35a5610112ea1611dd0eff01f8e63b8 /ext/compressors
parent21eac185168dcdc022d40adff36e688e70551e05 (diff)
downloadmongo-4c0881afeb6713ef7ae9ea2b8f61811b0fecd192.tar.gz
Use deflateCopy to copy streams for rollback in case the compressed size is too large.
refs SERVER-17713
Diffstat (limited to 'ext/compressors')
-rw-r--r--ext/compressors/zlib/zlib_compress.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/ext/compressors/zlib/zlib_compress.c b/ext/compressors/zlib/zlib_compress.c
index 0d843fd7626..24462f52680 100644
--- a/ext/compressors/zlib/zlib_compress.c
+++ b/ext/compressors/zlib/zlib_compress.c
@@ -265,7 +265,11 @@ zlib_compress_raw(WT_COMPRESSOR *compressor, WT_SESSION *session,
*/
#define WT_ZLIB_RESERVED 24
zs.avail_out = (uint32_t)(page_max - extra - WT_ZLIB_RESERVED);
- last_zs = zs;
+
+ /* Save the stream state in case the chosen data doesn't fit. */
+ if ((ret = deflateCopy(&last_zs, &zs)) != Z_OK)
+ return (zlib_error(
+ compressor, session, "deflateCopy", ret));
/*
* Strategy: take the available output size and compress that much
@@ -286,8 +290,6 @@ zlib_compress_raw(WT_COMPRESSOR *compressor, WT_SESSION *session,
break;
zs.avail_in = offsets[curr_slot] - offsets[last_slot];
- /* Save the stream state in case the chosen data doesn't fit. */
- last_zs = zs;
while (zs.avail_in > 0 && zs.avail_out > 0)
if ((ret = deflate(&zs, Z_SYNC_FLUSH)) != Z_OK)
@@ -296,12 +298,30 @@ zlib_compress_raw(WT_COMPRESSOR *compressor, WT_SESSION *session,
/* Roll back if the last deflate didn't complete. */
if (zs.avail_in > 0) {
- zs = last_zs;
+ if ((ret = deflateEnd(&zs)) != Z_OK &&
+ ret != Z_DATA_ERROR)
+ return (zlib_error(
+ compressor, session, "deflateEnd", ret));
+ if ((ret = deflateCopy(&zs, &last_zs)) != Z_OK)
+ return (zlib_error(
+ compressor, session, "deflateCopy", ret));
break;
- } else
+ } else {
+ if ((ret = deflateEnd(&last_zs)) != Z_OK &&
+ ret != Z_DATA_ERROR)
+ return (zlib_error(
+ compressor, session, "deflateEnd", ret));
+ if ((ret = deflateCopy(&last_zs, &zs)) != Z_OK)
+ return (zlib_error(
+ compressor, session, "deflateCopy", ret));
last_slot = curr_slot;
+ }
}
+ if ((ret = deflateEnd(&last_zs)) != Z_OK && ret != Z_DATA_ERROR)
+ return (zlib_error(
+ compressor, session, "deflateEnd", ret));
+
zs.avail_out += WT_ZLIB_RESERVED;
ret = deflate(&zs, Z_FINISH);