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):





