Ethereal-dev: [Ethereal-dev] Re: tvb_uncompress() performance improvements
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Jerry Talkington <jtalkington@xxxxxxxxxxxxxxxxxxxxx>
Date: Sun, 9 May 2004 20:28:10 -0700
On Sun, May 09, 2004 at 08:27:31PM -0700, Jerry Talkington wrote: > Here's a patch to speed up the tvb_uncompress() function. The previous > 4k buffer size made uncompressing large bodies extremely slow. This > patch makes the minimum buffer 32k, and the default twice as large as > the uncompressed data, with a maximum of 10Mb. Man, I need to work on my mutt attachment skills ;) -- GPG public key: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x9D5B8762
Index: epan/tvbuff.c =================================================================== RCS file: /cvsroot/ethereal/epan/tvbuff.c,v retrieving revision 1.64 diff -u -r1.64 tvbuff.c --- epan/tvbuff.c 7 May 2004 18:15:24 -0000 1.64 +++ epan/tvbuff.c 10 May 2004 03:21:53 -0000 @@ -2160,22 +2160,35 @@ * length comprlen. Returns an uncompressed tvbuffer if uncompression * succeeded or NULL if uncompression failed. */ -#define TVB_Z_BUFSIZ 4096 +#define TVB_Z_MIN_BUFSIZ 32768 +#define TVB_Z_MAX_BUFSIZ 1048576 * 10 +/* #define TVB_Z_DEBUG 1 */ +#undef TVB_Z_DEBUG + tvbuff_t * tvb_uncompress(tvbuff_t *tvb, int offset, int comprlen) { gint err = Z_OK; - gint bytes_out = 0; + guint bytes_out = 0; guint8 *compr = NULL; guint8 *uncompr = NULL; tvbuff_t *uncompr_tvb = NULL; z_streamp strm = NULL; - gchar strmbuf[TVB_Z_BUFSIZ]; - gint inits_done = 0; + Bytef *strmbuf = NULL; + guint inits_done = 0; gint wbits = MAX_WBITS; guint8 *next = NULL; + guint bufsiz = TVB_Z_MIN_BUFSIZ; +#ifdef TVB_Z_DEBUG + guint inflate_passes = 0; + guint bytes_in = tvb_length_remaining(tvb, offset); +#endif + + if (tvb == NULL) { + return NULL; + } strm = g_malloc0(sizeof(z_stream)); @@ -2189,41 +2202,70 @@ return NULL; } + /* + * Assume that the uncompressed data is at least twice as big as + * the compressed size. + */ + bufsiz = tvb_length_remaining(tvb, offset) * 2; + + if (bufsiz < TVB_Z_MIN_BUFSIZ) { + bufsiz = TVB_Z_MIN_BUFSIZ; + } else if (bufsiz > TVB_Z_MAX_BUFSIZ) { + bufsiz = TVB_Z_MIN_BUFSIZ; + } + +#ifdef TVB_Z_DEBUG + printf("bufsiz: %u bytes\n", bufsiz); +#endif + next = compr; strm->next_in = next; strm->avail_in = comprlen; - memset(&strmbuf, 0, TVB_Z_BUFSIZ); - strm->next_out = (Bytef *)&strmbuf; - strm->avail_out = TVB_Z_BUFSIZ; + + strmbuf = g_malloc0(bufsiz); + + if(strmbuf == NULL) { + g_free(compr); + return NULL; + } + + strm->next_out = strmbuf; + strm->avail_out = bufsiz; err = inflateInit2(strm, wbits); inits_done = 1; if (err != Z_OK) { g_free(strm); g_free(compr); + g_free(strmbuf); return NULL; } while (1) { - memset(&strmbuf, 0, TVB_Z_BUFSIZ); - strm->next_out = (Bytef *)&strmbuf; - strm->avail_out = TVB_Z_BUFSIZ; + memset(strmbuf, '\0', bufsiz); + strm->next_out = strmbuf; + strm->avail_out = bufsiz; err = inflate(strm, Z_SYNC_FLUSH); if (err == Z_OK || err == Z_STREAM_END) { - guint bytes_pass = TVB_Z_BUFSIZ - strm->avail_out; + guint bytes_pass = bufsiz - strm->avail_out; + +#ifdef TVB_Z_DEBUG + ++inflate_passes; +#endif if (uncompr == NULL) { - uncompr = g_memdup(&strmbuf, bytes_pass); + uncompr = g_memdup(strmbuf, bytes_pass); } else { guint8 *new_data = g_malloc0(bytes_out + bytes_pass); if (new_data == NULL) { g_free(strm); + g_free(strmbuf); g_free(compr); if (uncompr != NULL) { @@ -2234,7 +2276,7 @@ } g_memmove(new_data, uncompr, bytes_out); - g_memmove((new_data + bytes_out), &strmbuf, + g_memmove((new_data + bytes_out), strmbuf, bytes_pass); g_free(uncompr); @@ -2246,6 +2288,7 @@ if ( err == Z_STREAM_END) { inflateEnd(strm); g_free(strm); + g_free(strmbuf); break; } } else if (err == Z_BUF_ERROR) { @@ -2256,6 +2299,7 @@ */ g_free(strm); + g_free(strmbuf); if (uncompr != NULL) { break; @@ -2289,6 +2333,7 @@ } else { g_free(strm); g_free(compr); + g_free(strmbuf); return NULL; } @@ -2350,9 +2395,9 @@ strm->next_in = next; strm->avail_in = comprlen; - memset(&strmbuf, 0, TVB_Z_BUFSIZ); - strm->next_out = (Bytef *)&strmbuf; - strm->avail_out = TVB_Z_BUFSIZ; + memset(strmbuf, '\0', bufsiz); + strm->next_out = strmbuf; + strm->avail_out = bufsiz; err = inflateInit2(strm, wbits); @@ -2360,6 +2405,7 @@ if (err != Z_OK) { g_free(strm); + g_free(strmbuf); g_free(compr); g_free(uncompr); @@ -2367,6 +2413,7 @@ } } else { g_free(strm); + g_free(strmbuf); g_free(compr); if (uncompr == NULL) { @@ -2376,6 +2423,11 @@ break; } } + +#ifdef TVB_Z_DEBUG + printf("inflate() total passes: %u\n", inflate_passes); + printf("bytes in: %u\nbytes out: %u\n\n", bytes_in, bytes_out); +#endif if (uncompr != NULL) { uncompr_tvb = tvb_new_real_data((guint8*) uncompr, bytes_out,
- Follow-Ups:
- Re: [Ethereal-dev] Re: tvb_uncompress() performance improvements
- From: Olivier Biot
- Re: [Ethereal-dev] Re: tvb_uncompress() performance improvements
- References:
- [Ethereal-dev] tvb_uncompress() performance improvements
- From: Jerry Talkington
- [Ethereal-dev] tvb_uncompress() performance improvements
- Prev by Date: [Ethereal-dev] tvb_uncompress() performance improvements
- Next by Date: Re: [Ethereal-dev] HTTP gzip/deflate decompression patch - zlibandgzip on Win32
- Previous by thread: [Ethereal-dev] tvb_uncompress() performance improvements
- Next by thread: Re: [Ethereal-dev] Re: tvb_uncompress() performance improvements
- Index(es):