On Wed, Jan 12, 2005 at 03:57:43PM +0000, Colin Watson wrote: > https://svn.uhulinux.hu/packages/dev/zlib/patches/02-rsync.patch
> ... but I'm afraid I don't know its current state or whether there's a > newer version available. Attached in case the URL goes bad. Looks plausible at a first glance. -- "You grabbed my hand and we fell into it, like a daydream - or a fever."
diff -Naur zlib-1.2.1.orig/deflate.c zlib-1.2.1/deflate.c --- zlib-1.2.1.orig/deflate.c 2003-11-09 03:33:12.000000000 +0100 +++ zlib-1.2.1/deflate.c 2004-05-04 00:43:27.000000000 +0200 @@ -115,6 +115,17 @@ * See deflate.c for comments about the MIN_MATCH+1. */ +#ifndef RSYNC_WIN +# define RSYNC_WIN 4096 +#endif +/* Size of rsync window, must be < MAX_DIST */ + +#define RSYNC_SUM_MATCH(sum) ((sum) % RSYNC_WIN == 0) +/* Whether window sum matches magic value */ + +/* Global rsync mode control variable */ +int zlib_rsync = 0; + /* Values for max_lazy_match, good_match and max_chain_length, depending on * the desired pack level (0..9). The values given below have been tuned to * exclude worst case performance for pathological files. Better values may be @@ -841,6 +852,10 @@ #ifdef ASMV match_init(); /* initialize the asm code */ #endif + + /* rsync params */ + s->rsync_chunk_end = 0xFFFFFFFFUL; + s->rsync_sum = 0; } #ifndef FASTEST @@ -1123,6 +1138,8 @@ zmemcpy(s->window, s->window+wsize, (unsigned)wsize); s->match_start -= wsize; s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + if (s->rsync_chunk_end != 0xFFFFFFFFUL) + s->rsync_chunk_end -= wsize; s->block_start -= (long) wsize; /* Slide the hash table (could be avoided with 32 bit values @@ -1184,15 +1201,51 @@ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); } +local void rsync_roll(s, start, num) + deflate_state *s; + unsigned start; + unsigned num; +{ + unsigned i; + + if (start < RSYNC_WIN) { + /* before window fills. */ + for (i = start; i < RSYNC_WIN; i++) { + if (i == start + num) return; + s->rsync_sum += (ulg)s->window[i]; + } + num -= (RSYNC_WIN - start); + start = RSYNC_WIN; + } + + /* buffer after window full */ + for (i = start; i < start+num; i++) { + /* New character in */ + s->rsync_sum += (ulg)s->window[i]; + /* Old character out */ + s->rsync_sum -= (ulg)s->window[i - RSYNC_WIN]; + if (s->rsync_chunk_end == 0xFFFFFFFFUL + && RSYNC_SUM_MATCH(s->rsync_sum)) + s->rsync_chunk_end = i; + } +} + +/* =========================================================================== + * Set rsync_chunk_end if window sum matches magic value. + */ +#define RSYNC_ROLL(s, start, num) \ + do { if (zlib_rsync) rsync_roll((s), (start), (num)); } while(0) + /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ -#define FLUSH_BLOCK_ONLY(s, eof) { \ +#define FLUSH_BLOCK_ONLY(s, eof, pad) { \ _tr_flush_block(s, (s->block_start >= 0L ? \ (charf *)&s->window[(unsigned)s->block_start] : \ (charf *)Z_NULL), \ (ulg)((long)s->strstart - s->block_start), \ + (pad), \ (eof)); \ s->block_start = s->strstart; \ flush_pending(s->strm); \ @@ -1200,8 +1253,8 @@ } /* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, eof) { \ - FLUSH_BLOCK_ONLY(s, eof); \ +#define FLUSH_BLOCK(s, eof, pad) { \ + FLUSH_BLOCK_ONLY(s, eof, pad); \ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ } @@ -1252,16 +1305,16 @@ /* strstart == 0 is possible when wraparound on 16-bit machine */ s->lookahead = (uInt)(s->strstart - max_start); s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); + FLUSH_BLOCK(s, 0, 0); } /* Flush if we may have to slide, otherwise block_start may become * negative and the data will be gone: */ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); + FLUSH_BLOCK(s, 0, 0); } } - FLUSH_BLOCK(s, flush == Z_FINISH); + FLUSH_BLOCK(s, flush == Z_FINISH, 0); return flush == Z_FINISH ? finish_done : block_done; } @@ -1330,6 +1383,7 @@ s->lookahead -= s->match_length; + RSYNC_ROLL(s, s->strstart, s->match_length); /* Insert new strings in the hash table only if the match length * is not too large. This saves time but degrades compression. */ @@ -1363,12 +1417,17 @@ /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); _tr_tally_lit (s, s->window[s->strstart], bflush); + RSYNC_ROLL(s, s->strstart, 1); s->lookahead--; s->strstart++; } - if (bflush) FLUSH_BLOCK(s, 0); + if (zlib_rsync && s->strstart > s->rsync_chunk_end) { + s->rsync_chunk_end = 0xFFFFFFFFUL; + bflush = 2; + } + if (bflush) FLUSH_BLOCK(s, 0, bflush-1); } - FLUSH_BLOCK(s, flush == Z_FINISH); + FLUSH_BLOCK(s, flush == Z_FINISH, bflush-1); return flush == Z_FINISH ? finish_done : block_done; } @@ -1457,6 +1516,7 @@ */ s->lookahead -= s->prev_length-1; s->prev_length -= 2; + RSYNC_ROLL(s, s->strstart, s->prev_length+1); do { if (++s->strstart <= max_insert) { INSERT_STRING(s, s->strstart, hash_head); @@ -1466,7 +1526,11 @@ s->match_length = MIN_MATCH-1; s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); + if (zlib_rsync && s->strstart > s->rsync_chunk_end) { + s->rsync_chunk_end = 0xFFFFFFFFUL; + bflush = 2; + } + if (bflush) FLUSH_BLOCK(s, 0, bflush-1); } else if (s->match_available) { /* If there was no match at the previous position, output a @@ -1475,9 +1539,14 @@ */ Tracevv((stderr,"%c", s->window[s->strstart-1])); _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (zlib_rsync && s->strstart > s->rsync_chunk_end) { + s->rsync_chunk_end = 0xFFFFFFFFUL; + bflush = 2; + } if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); + FLUSH_BLOCK_ONLY(s, 0, bflush-1); } + RSYNC_ROLL(s, s->strstart, 1); s->strstart++; s->lookahead--; if (s->strm->avail_out == 0) return need_more; @@ -1485,7 +1554,14 @@ /* There is no previous match to compare with, wait for * the next step to decide. */ + if (zlib_rsync && s->strstart > s->rsync_chunk_end) { + /* Reset huffman tree */ + s->rsync_chunk_end = 0xFFFFFFFFUL; + bflush = 2; + FLUSH_BLOCK(s, 0, bflush-1); + } s->match_available = 1; + RSYNC_ROLL(s, s->strstart, 1); s->strstart++; s->lookahead--; } @@ -1496,7 +1572,7 @@ _tr_tally_lit(s, s->window[s->strstart-1], bflush); s->match_available = 0; } - FLUSH_BLOCK(s, flush == Z_FINISH); + FLUSH_BLOCK(s, flush == Z_FINISH, bflush-1); return flush == Z_FINISH ? finish_done : block_done; } #endif /* FASTEST */ diff -Naur zlib-1.2.1.orig/deflate.h zlib-1.2.1/deflate.h --- zlib-1.2.1.orig/deflate.h 2003-07-24 07:59:56.000000000 +0200 +++ zlib-1.2.1/deflate.h 2004-05-04 00:38:08.000000000 +0200 @@ -255,6 +255,9 @@ * are always zero. */ + ulg rsync_sum; /* rolling sum of rsync window */ + ulg rsync_chunk_end; /* next rsync sequence point */ + } FAR deflate_state; /* Output a byte on the stream. @@ -277,7 +280,7 @@ void _tr_init OF((deflate_state *s)); int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); + int pad, int eof)); void _tr_align OF((deflate_state *s)); void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, int eof)); diff -Naur zlib-1.2.1.orig/trees.c zlib-1.2.1/trees.c --- zlib-1.2.1.orig/trees.c 2003-09-15 01:48:50.000000000 +0200 +++ zlib-1.2.1/trees.c 2004-05-04 00:37:06.000000000 +0200 @@ -918,10 +918,11 @@ * Determine the best encoding for the current block: dynamic trees, static * trees or store, and output the encoded block to the zip file. */ -void _tr_flush_block(s, buf, stored_len, eof) +void _tr_flush_block(s, buf, stored_len, pad, eof) deflate_state *s; charf *buf; /* input block, or NULL if too old */ ulg stored_len; /* length of input block */ + int pad; /* pad output to byte boundary */ int eof; /* true if this is the last block for a file */ { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ @@ -1009,6 +1010,12 @@ #ifdef DEBUG s->compressed_len += 7; /* align on byte boundary */ #endif +#ifdef DEBUG + } else if (pad && (s->compressed_len % 8) != 0) { +#else + } else if (pad) { +#endif + _tr_stored_block(s, buf, 0, eof); } Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, s->compressed_len-7*eof)); diff -Naur zlib-1.2.1.orig/zlib.h zlib-1.2.1/zlib.h --- zlib-1.2.1.orig/zlib.h 2003-11-17 22:19:11.000000000 +0100 +++ zlib-1.2.1/zlib.h 2004-05-04 00:37:06.000000000 +0200 @@ -1193,6 +1193,10 @@ ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); +/* Global rsync mode control variable */ +extern int zlib_rsync; + + #ifdef __cplusplus } #endif