RFR: 8920687: Deflater.setLevel does not work as expected

Xueming Shen xueming.shen at oracle.com
Fri Sep 13 19:44:18 UTC 2013


Hi,

This is change to clarify the java doc to match the existing behavior.

If there is a "pending" level/strategy change (via setLevel/Stragety()) when
deflate(...) is invoked, the implementation goes down to zlib's 
deflateParams()
for deflating operation, which clearly specifies its behavior in zlib.h as

----------------------------------------------------------------
    Dynamically update the compression level and compression strategy.  The
    interpretation of level and strategy is as in deflateInit2.  This can be
    used to switch between compression and straight copy of the input 
data, or
    to switch to a different kind of input data requiring a different 
strategy.
    If the compression level is changed, the input available so far is
    compressed with the old level (and may be flushed); the new level 
will take
    effect only at the next call of deflate().
-----------------------------------------------------------------

and its corresponding implementation does exactly that.

Note, the zlib.h doc does not explicitly mention the "strategy", but 
it's implementation
treat the strategy and level the same way. The code looks like

-----------------------------------------------------------------
int ZEXPORT deflateParams(strm, level, strategy)
     z_streamp strm;
     int level;
     int strategy;
{
     deflate_state *s;
     compress_func func;
     int err = Z_OK;

     if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
     s = strm->state;

#ifdef FASTEST
     if (level != 0) level = 1;
#else
     if (level == Z_DEFAULT_COMPRESSION) level = 6;
#endif
     if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
         return Z_STREAM_ERROR;
     }
     func = configuration_table[s->level].func;

     if ((strategy != s->strategy || func != 
configuration_table[level].func) &&
         strm->total_in != 0) {
         /* Flush the last buffer: */
         err = deflate(strm, Z_BLOCK);
     }
     if (s->level != level) {
         s->level = level;
         s->max_lazy_match   = configuration_table[level].max_lazy;
         s->good_match       = configuration_table[level].good_length;
         s->nice_match       = configuration_table[level].nice_length;
         s->max_chain_length = configuration_table[level].max_chain;
     }
     s->strategy = strategy;
     return err;
}
-------------------------------------------------------------------

The proposed change here is to add some words to clarify the expected 
behavior,
in which the next deflate() invocation after the setLevel/Strategy() 
will just finish
any left input (and may flush the buffer out). The new level/strategy 
will take
effect after that.

http://cr.openjdk.java.net/~sherman/8020687/webrev/

Thanks,
-Sherman





More information about the core-libs-dev mailing list