diff options
author | Keith Bostic <keith@wiredtiger.com> | 2015-03-25 13:01:15 -0400 |
---|---|---|
committer | Keith Bostic <keith@wiredtiger.com> | 2015-03-25 13:01:15 -0400 |
commit | 2c24dd0feaf71609dedcd4343fddbe332d106b45 (patch) | |
tree | d6cac3f9cba1258924aecafdd141885aa6e64e62 | |
parent | 4c0881afeb6713ef7ae9ea2b8f61811b0fecd192 (diff) | |
download | mongo-2c24dd0feaf71609dedcd4343fddbe332d106b45.tar.gz |
Shuffle the logic and add a pointer to remove some deflateCopy/deflateEnd
calls.
Minor lint, whitespace while in the area.
-rw-r--r-- | ext/compressors/zlib/zlib_compress.c | 110 |
1 files changed, 59 insertions, 51 deletions
diff --git a/ext/compressors/zlib/zlib_compress.c b/ext/compressors/zlib/zlib_compress.c index 24462f52680..da8e554008e 100644 --- a/ext/compressors/zlib/zlib_compress.c +++ b/ext/compressors/zlib/zlib_compress.c @@ -143,7 +143,7 @@ zlib_compress(WT_COMPRESSOR *compressor, WT_SESSION *session, zs.avail_out = (uint32_t)dst_len; if (deflate(&zs, Z_FINISH) == Z_STREAM_END) { *compression_failed = 0; - *result_lenp = zs.total_out; + *result_lenp = (size_t)zs.total_out; } else *compression_failed = 1; @@ -158,7 +158,7 @@ zlib_compress(WT_COMPRESSOR *compressor, WT_SESSION *session, * Find the slot containing the target offset (binary search). */ static inline uint32_t -zlib_find_slot(uint32_t target, uint32_t *offsets, uint32_t slots) +zlib_find_slot(u_long target, uint32_t *offsets, uint32_t slots) { uint32_t base, indx, limit; @@ -210,7 +210,7 @@ zlib_decompress(WT_COMPRESSOR *compressor, WT_SESSION *session, while ((ret = inflate(&zs, Z_FINISH)) == Z_OK) ; if (ret == Z_STREAM_END) { - *result_lenp = zs.total_out; + *result_lenp = (size_t)zs.total_out; ret = Z_OK; } @@ -234,7 +234,7 @@ zlib_compress_raw(WT_COMPRESSOR *compressor, WT_SESSION *session, { ZLIB_COMPRESSOR *zlib_compressor; ZLIB_OPAQUE opaque; - z_stream last_zs, zs; + z_stream *best_zs, last_zs, zs; uint32_t curr_slot, last_slot; int ret; @@ -252,8 +252,7 @@ zlib_compress_raw(WT_COMPRESSOR *compressor, WT_SESSION *session, opaque.session = session; zs.opaque = &opaque; - if ((ret = deflateInit(&zs, - zlib_compressor->zlib_level)) != Z_OK) + if ((ret = deflateInit(&zs, zlib_compressor->zlib_level)) != Z_OK) return (zlib_error(compressor, session, "deflateInit", ret)); zs.next_in = src; @@ -264,7 +263,7 @@ zlib_compress_raw(WT_COMPRESSOR *compressor, WT_SESSION *session, * inefficient. */ #define WT_ZLIB_RESERVED 24 - zs.avail_out = (uint32_t)(page_max - extra - WT_ZLIB_RESERVED); + zs.avail_out = (uint32_t)(page_max - (extra + WT_ZLIB_RESERVED)); /* Save the stream state in case the chosen data doesn't fit. */ if ((ret = deflateCopy(&last_zs, &zs)) != Z_OK) @@ -275,60 +274,68 @@ zlib_compress_raw(WT_COMPRESSOR *compressor, WT_SESSION *session, * Strategy: take the available output size and compress that much * input. Continue until there is no input small enough or the * compression fails to fit. - * - * Don't let the compression ratio become insanely good (which can - * happen with synthetic workloads). Once we hit a limit, stop so that - * the in-memory size of pages isn't totally different to the on-disk - * size. Otherwise we can get into trouble where every update to a - * page results in forced eviction based on in-memory size, even though - * the data fits into a single on-disk block. */ - while (zs.avail_out > 0 && zs.total_in <= zs.total_out * 20) { - /* Find the slot we will try to compress up to. */ + for (best_zs = NULL;;) { + /* Find the next slot we will try to compress up to. */ if ((curr_slot = zlib_find_slot( - zs.total_in + zs.avail_out, offsets, slots)) <= last_slot) - break; - - zs.avail_in = offsets[curr_slot] - offsets[last_slot]; - - while (zs.avail_in > 0 && zs.avail_out > 0) - if ((ret = deflate(&zs, Z_SYNC_FLUSH)) != Z_OK) - return (zlib_error( - compressor, session, "deflate", ret)); + zs.total_in + zs.avail_out, offsets, slots)) > last_slot) { + zs.avail_in = offsets[curr_slot] - offsets[last_slot]; + while (zs.avail_in > 0 && zs.avail_out > 0) + if ((ret = deflate(&zs, Z_SYNC_FLUSH)) != Z_OK) + return (zlib_error(compressor, + session, "deflate", ret)); + } - /* Roll back if the last deflate didn't complete. */ - if (zs.avail_in > 0) { + /* + * We didn't do a deflate, or it didn't work: use the last saved + * position. + */ + if (curr_slot <= last_slot || zs.avail_in > 0) { 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)); + + best_zs = &last_zs; break; - } else { - if ((ret = deflateEnd(&last_zs)) != Z_OK && - ret != Z_DATA_ERROR) - return (zlib_error( - compressor, session, "deflateEnd", ret)); + } + + /* The last deflation succeeded, discard the saved one. */ + if ((ret = deflateEnd(&last_zs)) != Z_OK && ret != Z_DATA_ERROR) + return (zlib_error( + compressor, session, "deflateEnd", ret)); + + /* + * If there's more compression to do, save a snapshot and keep + * going, otherwise, use the current compression. + * + * Don't let the compression ratio become insanely good (which + * can happen with synthetic workloads). Once we hit a limit, + * stop so the in-memory size of pages isn't hugely larger than + * the on-disk size, otherwise we can get into trouble where + * every update to a page results in forced eviction based on + * the in-memory size, even though the data fits into a single + * on-disk block. + */ + last_slot = curr_slot; + if (zs.avail_out > 0 && zs.total_in <= zs.total_out * 20) { if ((ret = deflateCopy(&last_zs, &zs)) != Z_OK) return (zlib_error( compressor, session, "deflateCopy", ret)); - last_slot = curr_slot; + continue; } - } - if ((ret = deflateEnd(&last_zs)) != Z_OK && ret != Z_DATA_ERROR) - return (zlib_error( - compressor, session, "deflateEnd", ret)); + best_zs = &zs; + break; + } - zs.avail_out += WT_ZLIB_RESERVED; - ret = deflate(&zs, Z_FINISH); + best_zs->avail_out += WT_ZLIB_RESERVED; + ret = deflate(best_zs, Z_FINISH); /* - * If the end marker didn't fit, report that we got no work done. WT - * will compress the (possibly large) page image using ordinary - * compression instead. + * If the end marker didn't fit, report that we got no work done, + * WiredTiger will compress the (possibly large) page image using + * ordinary compression instead. */ if (ret == Z_OK || ret == Z_BUF_ERROR) last_slot = 0; @@ -336,12 +343,12 @@ zlib_compress_raw(WT_COMPRESSOR *compressor, WT_SESSION *session, return ( zlib_error(compressor, session, "deflate end block", ret)); - if ((ret = deflateEnd(&zs)) != Z_OK && ret != Z_DATA_ERROR) + if ((ret = deflateEnd(best_zs)) != Z_OK && ret != Z_DATA_ERROR) return (zlib_error(compressor, session, "deflateEnd", ret)); if (last_slot > 0) { *result_slotsp = last_slot; - *result_lenp = zs.total_out; + *result_lenp = (size_t)best_zs->total_out; } else { /* We didn't manage to compress anything: don't retry. */ *result_slotsp = 0; @@ -354,11 +361,12 @@ zlib_compress_raw(WT_COMPRESSOR *compressor, WT_SESSION *session, void *decomp; size_t result_len; - if ((decomp = - zalloc(&opaque, 1, (uint32_t)zs.total_in + 100)) == NULL) + if ((decomp = zalloc( + &opaque, 1, (uint32_t)best_zs->total_in + 100)) == NULL) return (ENOMEM); - if ((ret = zlib_decompress(compressor, session, dst, - zs.total_out, decomp, zs.total_in + 100, &result_len)) == 0) + if ((ret = zlib_decompress( + compressor, session, dst, (size_t)best_zs->total_out, + decomp, (size_t)best_zs->total_in + 100, &result_len)) == 0) if (memcmp(src, decomp, result_len) != 0) ret = zlib_error(compressor, session, "deflate compare with original source", |