diff options
| author | Nathan Moinvaziri <nathan@nathanm.com> | 2026-03-09 19:39:52 -0700 |
|---|---|---|
| committer | Hans Kristian Rosbach <hk-github@circlestorm.org> | 2026-03-12 17:01:27 +0100 |
| commit | 9d951c0eec5dc7f1629e1789b102c99a90de943f (patch) | |
| tree | 7c17de0edaa1daa83372218e9107c2ac901effc8 | |
| parent | 269036cc05baad4c0aa749df3c325738197eba09 (diff) | |
| download | Project-Tick-9d951c0eec5dc7f1629e1789b102c99a90de943f.tar.gz Project-Tick-9d951c0eec5dc7f1629e1789b102c99a90de943f.zip | |
Separate match finding logic in deflate_medium
| -rw-r--r-- | deflate_medium.c | 89 |
1 files changed, 34 insertions, 55 deletions
diff --git a/deflate_medium.c b/deflate_medium.c index 056cde3c8e..f67e1b60e7 100644 --- a/deflate_medium.c +++ b/deflate_medium.c @@ -90,6 +90,36 @@ static void insert_match(deflate_state *s, struct match match) { } } +Z_FORCEINLINE static struct match find_best_match(deflate_state *s, uint32_t hash_head) { + struct match m; + int64_t dist; + + m.strstart = (uint16_t)s->strstart; + m.orgstart = m.strstart; + + dist = (int64_t)s->strstart - hash_head; + if (dist <= MAX_DIST(s) && dist > 0 && hash_head != 0) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + m.match_length = (uint16_t)FUNCTABLE_CALL(longest_match)(s, hash_head); + m.match_start = (uint16_t)s->match_start; + if (UNLIKELY(m.match_length < WANT_MIN_MATCH)) + m.match_length = 1; + if (UNLIKELY(m.match_start >= m.strstart)) { + /* this can happen due to some restarts */ + m.match_length = 1; + } + } else { + /* Set up the match to be a 1 byte literal */ + m.match_start = 0; + m.match_length = 1; + } + + return m; +} + static void fizzle_matches(deflate_state *s, struct match *current, struct match *next) { unsigned char *window; unsigned char *match, *orig; @@ -167,7 +197,6 @@ Z_INTERNAL block_state deflate_medium(deflate_state *s, int flush) { for (;;) { uint32_t hash_head = 0; /* head of the hash chain */ int bflush = 0; /* set if current block must be flushed */ - int64_t dist; /* Make sure that we always have enough lookahead, except * at the end of the input file. We need STD_MAX_MATCH bytes @@ -198,32 +227,7 @@ Z_INTERNAL block_state deflate_medium(deflate_state *s, int flush) { hash_head = quick_insert_string(s, s->strstart); } - current_match.strstart = (uint16_t)s->strstart; - current_match.orgstart = current_match.strstart; - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < WANT_MIN_MATCH - */ - - dist = (int64_t)s->strstart - hash_head; - if (dist <= MAX_DIST(s) && dist > 0 && hash_head != 0) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - current_match.match_length = (uint16_t)FUNCTABLE_CALL(longest_match)(s, hash_head); - current_match.match_start = (uint16_t)s->match_start; - if (UNLIKELY(current_match.match_length < WANT_MIN_MATCH)) - current_match.match_length = 1; - if (UNLIKELY(current_match.match_start >= current_match.strstart)) { - /* this can happen due to some restarts */ - current_match.match_length = 1; - } - } else { - /* Set up the match to be a 1 byte literal */ - current_match.match_start = 0; - current_match.match_length = 1; - } + current_match = find_best_match(s, hash_head); } insert_match(s, current_match); @@ -233,34 +237,9 @@ Z_INTERNAL block_state deflate_medium(deflate_state *s, int flush) { s->strstart = current_match.strstart + current_match.match_length; hash_head = quick_insert_string(s, s->strstart); - next_match.strstart = (uint16_t)s->strstart; - next_match.orgstart = next_match.strstart; - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < WANT_MIN_MATCH - */ - - dist = (int64_t)s->strstart - hash_head; - if (dist <= MAX_DIST(s) && dist > 0 && hash_head != 0) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - next_match.match_length = (uint16_t)FUNCTABLE_CALL(longest_match)(s, hash_head); - next_match.match_start = (uint16_t)s->match_start; - if (UNLIKELY(next_match.match_start >= next_match.strstart)) { - /* this can happen due to some restarts */ - next_match.match_length = 1; - } - if (next_match.match_length < WANT_MIN_MATCH) - next_match.match_length = 1; - else - fizzle_matches(s, ¤t_match, &next_match); - } else { - /* Set up the match to be a 1 byte literal */ - next_match.match_start = 0; - next_match.match_length = 1; - } + next_match = find_best_match(s, hash_head); + if (next_match.match_length >= WANT_MIN_MATCH) + fizzle_matches(s, ¤t_match, &next_match); s->strstart = current_match.strstart; } else { |
