diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2015-03-25 12:13:08 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2015-03-25 12:13:08 +1100 |
commit | 4c0881afeb6713ef7ae9ea2b8f61811b0fecd192 (patch) | |
tree | 16f02247c35a5610112ea1611dd0eff01f8e63b8 /ext | |
parent | 21eac185168dcdc022d40adff36e688e70551e05 (diff) | |
download | mongo-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')
-rw-r--r-- | ext/compressors/zlib/zlib_compress.c | 30 |
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); |