diff options
author | josh.macdonald <jmacd@users.noreply.github.com> | 2007-02-04 09:30:02 +0000 |
---|---|---|
committer | josh.macdonald <jmacd@users.noreply.github.com> | 2007-02-04 09:30:02 +0000 |
commit | 400e5c3f9edbfedfa770c94c04e62aa8657ed04a (patch) | |
tree | a929bd434ec27cb53846fd43c910a244d3585011 /xdelta3/xdelta3.c | |
parent | 1e10015476fb24d78d0b14de6a7819586037382d (diff) |
Adds a new compression level (-6), makes -1 faster and -9 better.
Diffstat (limited to 'xdelta3/xdelta3.c')
-rwxr-xr-x | xdelta3/xdelta3.c | 183 |
1 files changed, 94 insertions, 89 deletions
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index f8c0bc7..4941408 100755 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -473,10 +473,16 @@ XD3_MAKELIST(xd3_rlist, xd3_rinst, link); | |||
473 | #else | 473 | #else |
474 | #define IF_BUILD_SOFT(x) | 474 | #define IF_BUILD_SOFT(x) |
475 | #endif | 475 | #endif |
476 | #if XD3_BUILD_DEFAULT | ||
477 | #define IF_BUILD_DEFAULT(x) x | ||
478 | #else | ||
479 | #define IF_BUILD_DEFAULT(x) | ||
480 | #endif | ||
476 | 481 | ||
477 | IF_BUILD_SOFT(static const xd3_smatcher __smatcher_soft;) | 482 | IF_BUILD_SOFT(static const xd3_smatcher __smatcher_soft;) |
478 | IF_BUILD_FAST(static const xd3_smatcher __smatcher_fast;) | 483 | IF_BUILD_FAST(static const xd3_smatcher __smatcher_fast;) |
479 | IF_BUILD_SLOW(static const xd3_smatcher __smatcher_slow;) | 484 | IF_BUILD_SLOW(static const xd3_smatcher __smatcher_slow;) |
485 | IF_BUILD_DEFAULT(static const xd3_smatcher __smatcher_default;) | ||
480 | 486 | ||
481 | #if XD3_DEBUG | 487 | #if XD3_DEBUG |
482 | #define SMALL_HASH_DEBUG1(s,inp) \ | 488 | #define SMALL_HASH_DEBUG1(s,inp) \ |
@@ -577,7 +583,6 @@ static usize_t xd3_sizeof_output (xd3_output *output); | |||
577 | static int xd3_source_match_setup (xd3_stream *stream, xoff_t srcpos); | 583 | static int xd3_source_match_setup (xd3_stream *stream, xoff_t srcpos); |
578 | static int xd3_source_extend_match (xd3_stream *stream); | 584 | static int xd3_source_extend_match (xd3_stream *stream); |
579 | static int xd3_srcwin_setup (xd3_stream *stream); | 585 | static int xd3_srcwin_setup (xd3_stream *stream); |
580 | static int xd3_srcwin_move_point (xd3_stream *stream, usize_t *next_move_point); | ||
581 | static usize_t xd3_iopt_last_matched (xd3_stream *stream); | 586 | static usize_t xd3_iopt_last_matched (xd3_stream *stream); |
582 | static int xd3_emit_uint32_t (xd3_stream *stream, xd3_output **output, uint32_t num); | 587 | static int xd3_emit_uint32_t (xd3_stream *stream, xd3_output **output, uint32_t num); |
583 | 588 | ||
@@ -2514,7 +2519,9 @@ xd3_config_stream(xd3_stream *stream, | |||
2514 | break; | 2519 | break; |
2515 | }) | 2520 | }) |
2516 | 2521 | ||
2517 | IF_BUILD_SLOW(case XD3_SMATCH_DEFAULT:) | 2522 | IF_BUILD_DEFAULT(case XD3_SMATCH_DEFAULT: |
2523 | *smatcher = __smatcher_default; | ||
2524 | break;) | ||
2518 | IF_BUILD_SLOW(case XD3_SMATCH_SLOW: | 2525 | IF_BUILD_SLOW(case XD3_SMATCH_SLOW: |
2519 | *smatcher = __smatcher_slow; | 2526 | *smatcher = __smatcher_slow; |
2520 | break;) | 2527 | break;) |
@@ -4061,6 +4068,89 @@ xd3_string_match_init (xd3_stream *stream) | |||
4061 | return 0; | 4068 | return 0; |
4062 | } | 4069 | } |
4063 | 4070 | ||
4071 | /* This function handles the 32/64bit ambiguity -- file positions are 64bit but the hash | ||
4072 | * table for source-offsets is 32bit. */ | ||
4073 | static xoff_t | ||
4074 | xd3_source_cksum_offset(xd3_stream *stream, usize_t low) | ||
4075 | { | ||
4076 | xoff_t scp = stream->srcwin_cksum_pos; | ||
4077 | xoff_t s0 = scp >> 32; | ||
4078 | |||
4079 | usize_t sr = (usize_t) scp; | ||
4080 | |||
4081 | if (s0 == 0) { | ||
4082 | return low; | ||
4083 | } | ||
4084 | |||
4085 | // This should not be >= because srcwin_cksum_pos is the next position to index | ||
4086 | if (low > sr) { | ||
4087 | return (--s0 << 32) | low; | ||
4088 | } | ||
4089 | |||
4090 | return (s0 << 32) | low; | ||
4091 | } | ||
4092 | |||
4093 | /* This function sets up the stream->src fields srcbase, srclen. The call is delayed | ||
4094 | * until these values are needed to encode a copy address. At this point the decision has | ||
4095 | * to be made. */ | ||
4096 | static int | ||
4097 | xd3_srcwin_setup (xd3_stream *stream) | ||
4098 | { | ||
4099 | xd3_source *src = stream->src; | ||
4100 | xoff_t length; | ||
4101 | |||
4102 | /* Check the undecided state. */ | ||
4103 | XD3_ASSERT (src->srclen == 0 && src->srcbase == 0); | ||
4104 | |||
4105 | /* Avoid repeating this call. */ | ||
4106 | stream->srcwin_decided = 1; | ||
4107 | |||
4108 | /* If the stream is flushing, then the iopt buffer was able to contain the complete | ||
4109 | * encoding. If no copies were issued no source window is actually needed. This | ||
4110 | * prevents the VCDIFF header from including source base/len. xd3_emit_hdr checks | ||
4111 | * for srclen == 0. */ | ||
4112 | if (stream->enc_state == ENC_FLUSH && stream->match_maxaddr == 0) | ||
4113 | { | ||
4114 | goto done; | ||
4115 | } | ||
4116 | |||
4117 | /* Check for overflow, srclen is usize_t - this can't happen unless XD3_DEFAULT_SRCBACK | ||
4118 | * and related parameters are extreme - should use smaller windows. */ | ||
4119 | length = stream->match_maxaddr - stream->match_minaddr; | ||
4120 | |||
4121 | if (length > (xoff_t) USIZE_T_MAX) | ||
4122 | { | ||
4123 | stream->msg = "source window length overflow (not 64bit)"; | ||
4124 | return XD3_INTERNAL; | ||
4125 | } | ||
4126 | |||
4127 | /* If ENC_FLUSH, then we know the exact source window to use because no more copies can | ||
4128 | * be issued. */ | ||
4129 | if (stream->enc_state == ENC_FLUSH) | ||
4130 | { | ||
4131 | src->srcbase = stream->match_minaddr; | ||
4132 | src->srclen = (usize_t) length; | ||
4133 | XD3_ASSERT (src->srclen); | ||
4134 | goto done; | ||
4135 | } | ||
4136 | |||
4137 | /* Otherwise, we have to make a guess. More copies may still be issued, but we have to | ||
4138 | * decide the source window base and length now. */ | ||
4139 | src->srcbase = stream->match_minaddr; | ||
4140 | src->srclen = max ((usize_t) length, stream->avail_in + (stream->avail_in >> 2)); | ||
4141 | if (src->size < src->srcbase + (xoff_t) src->srclen) | ||
4142 | { | ||
4143 | /* Could reduce srcbase, as well. */ | ||
4144 | src->srclen = src->size - src->srcbase; | ||
4145 | } | ||
4146 | |||
4147 | XD3_ASSERT (src->srclen); | ||
4148 | done: | ||
4149 | /* Set the taroff. This convenience variable is used even when stream->src == NULL. */ | ||
4150 | stream->taroff = src->srclen; | ||
4151 | return 0; | ||
4152 | } | ||
4153 | |||
4064 | /* Called at every entrance to the string-match loop and each time | 4154 | /* Called at every entrance to the string-match loop and each time |
4065 | * stream->input_position the value returned as *next_move_point. | 4155 | * stream->input_position the value returned as *next_move_point. |
4066 | * This function computes more source checksums to advance the window. */ | 4156 | * This function computes more source checksums to advance the window. */ |
@@ -4138,14 +4228,12 @@ xd3_srcwin_move_point (xd3_stream *stream, usize_t *next_move_point) | |||
4138 | diff = logical_input_cksum_pos - stream->srcwin_cksum_pos; | 4228 | diff = logical_input_cksum_pos - stream->srcwin_cksum_pos; |
4139 | onblk = min(blkoff + diff, onblk); | 4229 | onblk = min(blkoff + diff, onblk); |
4140 | 4230 | ||
4141 | /* TODO: This block needs to be included in the template pass... duh. | ||
4142 | */ | ||
4143 | |||
4144 | /* Note: I experimented with rewriting this block to use LARGE_CKSUM_UPDATE() | 4231 | /* Note: I experimented with rewriting this block to use LARGE_CKSUM_UPDATE() |
4145 | * instead of recalculating the cksum every N bytes. It seemed to make performance | 4232 | * instead of recalculating the cksum every N bytes. It seemed to make performance |
4146 | * worse. */ | 4233 | * worse (except obviously for step == 1, not worth extra complexity) */ |
4147 | while (blkoff <= onblk) | 4234 | while (blkoff <= onblk) |
4148 | { | 4235 | { |
4236 | /* It's a big win to have the compiler optimize this loop w/ fi. */ | ||
4149 | uint32_t cksum = xd3_lcksum (stream->src->curblk + blkoff, stream->smatcher.large_look); | 4237 | uint32_t cksum = xd3_lcksum (stream->src->curblk + blkoff, stream->smatcher.large_look); |
4150 | usize_t hval = xd3_checksum_hash (& stream->large_hash, cksum); | 4238 | usize_t hval = xd3_checksum_hash (& stream->large_hash, cksum); |
4151 | 4239 | ||
@@ -4167,89 +4255,6 @@ xd3_srcwin_move_point (xd3_stream *stream, usize_t *next_move_point) | |||
4167 | return 0; | 4255 | return 0; |
4168 | } | 4256 | } |
4169 | 4257 | ||
4170 | /* This function handles the 32/64bit ambiguity -- file positions are 64bit but the hash | ||
4171 | * table for source-offsets is 32bit. */ | ||
4172 | static xoff_t | ||
4173 | xd3_source_cksum_offset(xd3_stream *stream, usize_t low) | ||
4174 | { | ||
4175 | xoff_t scp = stream->srcwin_cksum_pos; | ||
4176 | xoff_t s0 = scp >> 32; | ||
4177 | |||
4178 | usize_t sr = (usize_t) scp; | ||
4179 | |||
4180 | if (s0 == 0) { | ||
4181 | return low; | ||
4182 | } | ||
4183 | |||
4184 | // This should not be >= because srcwin_cksum_pos is the next position to index | ||
4185 | if (low > sr) { | ||
4186 | return (--s0 << 32) | low; | ||
4187 | } | ||
4188 | |||
4189 | return (s0 << 32) | low; | ||
4190 | } | ||
4191 | |||
4192 | /* This function sets up the stream->src fields srcbase, srclen. The call is delayed | ||
4193 | * until these values are needed to encode a copy address. At this point the decision has | ||
4194 | * to be made. */ | ||
4195 | static int | ||
4196 | xd3_srcwin_setup (xd3_stream *stream) | ||
4197 | { | ||
4198 | xd3_source *src = stream->src; | ||
4199 | xoff_t length; | ||
4200 | |||
4201 | /* Check the undecided state. */ | ||
4202 | XD3_ASSERT (src->srclen == 0 && src->srcbase == 0); | ||
4203 | |||
4204 | /* Avoid repeating this call. */ | ||
4205 | stream->srcwin_decided = 1; | ||
4206 | |||
4207 | /* If the stream is flushing, then the iopt buffer was able to contain the complete | ||
4208 | * encoding. If no copies were issued no source window is actually needed. This | ||
4209 | * prevents the VCDIFF header from including source base/len. xd3_emit_hdr checks | ||
4210 | * for srclen == 0. */ | ||
4211 | if (stream->enc_state == ENC_FLUSH && stream->match_maxaddr == 0) | ||
4212 | { | ||
4213 | goto done; | ||
4214 | } | ||
4215 | |||
4216 | /* Check for overflow, srclen is usize_t - this can't happen unless XD3_DEFAULT_SRCBACK | ||
4217 | * and related parameters are extreme - should use smaller windows. */ | ||
4218 | length = stream->match_maxaddr - stream->match_minaddr; | ||
4219 | |||
4220 | if (length > (xoff_t) USIZE_T_MAX) | ||
4221 | { | ||
4222 | stream->msg = "source window length overflow (not 64bit)"; | ||
4223 | return XD3_INTERNAL; | ||
4224 | } | ||
4225 | |||
4226 | /* If ENC_FLUSH, then we know the exact source window to use because no more copies can | ||
4227 | * be issued. */ | ||
4228 | if (stream->enc_state == ENC_FLUSH) | ||
4229 | { | ||
4230 | src->srcbase = stream->match_minaddr; | ||
4231 | src->srclen = (usize_t) length; | ||
4232 | XD3_ASSERT (src->srclen); | ||
4233 | goto done; | ||
4234 | } | ||
4235 | |||
4236 | /* Otherwise, we have to make a guess. More copies may still be issued, but we have to | ||
4237 | * decide the source window base and length now. */ | ||
4238 | src->srcbase = stream->match_minaddr; | ||
4239 | src->srclen = max ((usize_t) length, stream->avail_in + (stream->avail_in >> 2)); | ||
4240 | if (src->size < src->srcbase + (xoff_t) src->srclen) | ||
4241 | { | ||
4242 | /* Could reduce srcbase, as well. */ | ||
4243 | src->srclen = src->size - src->srcbase; | ||
4244 | } | ||
4245 | |||
4246 | XD3_ASSERT (src->srclen); | ||
4247 | done: | ||
4248 | /* Set the taroff. This convenience variable is used even when stream->src == NULL. */ | ||
4249 | stream->taroff = src->srclen; | ||
4250 | return 0; | ||
4251 | } | ||
4252 | |||
4253 | /* Sets the bounding region for a newly discovered source match, prior to calling | 4258 | /* Sets the bounding region for a newly discovered source match, prior to calling |
4254 | * xd3_source_extend_match(). This sets the match_maxfwd, match_maxback variables. Note: | 4259 | * xd3_source_extend_match(). This sets the match_maxfwd, match_maxback variables. Note: |
4255 | * srcpos is an absolute position (xoff_t) but the match_maxfwd, match_maxback variables | 4260 | * srcpos is an absolute position (xoff_t) but the match_maxfwd, match_maxback variables |