1 ///////////////////////////////////////////////////////////////////////////////
3 /// \file lz_encoder_mf.c
4 /// \brief Match finders
6 // Authors: Igor Pavlov
9 // This file has been put into the public domain.
10 // You can do whatever you want with this file.
12 ///////////////////////////////////////////////////////////////////////////////
14 #include "lz_encoder.h"
15 #include "lz_encoder_hash.h"
18 /// \brief Find matches starting from the current byte
20 /// \return The length of the longest match found
22 lzma_mf_find(lzma_mf *mf, uint32_t *count_ptr, lzma_match *matches)
24 // Call the match finder. It returns the number of length-distance
26 // FIXME: Minimum count is zero, what _exactly_ is the maximum?
27 const uint32_t count = mf->find(mf, matches);
29 // Length of the longest match; assume that no matches were found
30 // and thus the maximum length is zero.
31 uint32_t len_best = 0;
35 // Validate the matches.
36 for (uint32_t i = 0; i < count; ++i) {
37 assert(matches[i].len <= mf->nice_len);
38 assert(matches[i].dist < mf->read_pos);
39 assert(memcmp(mf_ptr(mf) - 1,
40 mf_ptr(mf) - matches[i].dist - 2,
41 matches[i].len) == 0);
45 // The last used element in the array contains
47 len_best = matches[count - 1].len;
49 // If a match of maximum search length was found, try to
50 // extend the match to maximum possible length.
51 if (len_best == mf->nice_len) {
52 // The limit for the match length is either the
53 // maximum match length supported by the LZ-based
54 // encoder or the number of bytes left in the
55 // dictionary, whichever is smaller.
56 uint32_t limit = mf_avail(mf) + 1;
57 if (limit > mf->match_len_max)
58 limit = mf->match_len_max;
60 // Pointer to the byte we just ran through
62 const uint8_t *p1 = mf_ptr(mf) - 1;
64 // Pointer to the beginning of the match. We need -1
65 // here because the match distances are zero based.
66 const uint8_t *p2 = p1 - matches[count - 1].dist - 1;
68 while (len_best < limit
69 && p1[len_best] == p2[len_best])
76 // Finally update the read position to indicate that match finder was
77 // run for this dictionary offset.
84 /// Hash value to indicate unused element in the hash. Since we start the
85 /// positions from dict_size + 1, zero is always too far to qualify
86 /// as usable match position.
87 #define EMPTY_HASH_VALUE 0
90 /// Normalization must be done when lzma_mf.offset + lzma_mf.read_pos
91 /// reaches MUST_NORMALIZE_POS.
92 #define MUST_NORMALIZE_POS UINT32_MAX
95 /// \brief Normalizes hash values
97 /// The hash arrays store positions of match candidates. The positions are
98 /// relative to an arbitrary offset that is not the same as the absolute
99 /// offset in the input stream. The relative position of the current byte
100 /// is lzma_mf.offset + lzma_mf.read_pos. The distances of the matches are
101 /// the differences of the current read position and the position found from
104 /// To prevent integer overflows of the offsets stored in the hash arrays,
105 /// we need to "normalize" the stored values now and then. During the
106 /// normalization, we drop values that indicate distance greater than the
107 /// dictionary size, thus making space for new values.
109 normalize(lzma_mf *mf)
111 assert(mf->read_pos + mf->offset == MUST_NORMALIZE_POS);
113 // In future we may not want to touch the lowest bits, because there
114 // may be match finders that use larger resolution than one byte.
115 const uint32_t subvalue
116 = (MUST_NORMALIZE_POS - mf->cyclic_size);
117 // & (~(UINT32_C(1) << 10) - 1);
119 const uint32_t count = mf->hash_size_sum + mf->sons_count;
120 uint32_t *hash = mf->hash;
123 for (i = 0; i < count; ++i) {
124 // If the distance is greater than the dictionary size,
125 // we can simply mark the hash element as empty.
127 // NOTE: Only the first mf->hash_size_sum elements are
128 // initialized for sure. There may be uninitialized elements
129 // in mf->son. Since we go through both mf->hash and
130 // mf->son here in normalization, Valgrind may complain
131 // that the "if" below depends on uninitialized value. In
132 // this case it is safe to ignore the warning. See also the
133 // comments in lz_encoder_init() in lz_encoder.c.
134 if (hash[i] <= subvalue)
135 hash[i] = EMPTY_HASH_VALUE;
140 // Update offset to match the new locations.
141 mf->offset -= subvalue;
147 /// Mark the current byte as processed from point of view of the match finder.
149 move_pos(lzma_mf *mf)
151 if (++mf->cyclic_pos == mf->cyclic_size)
155 assert(mf->read_pos <= mf->write_pos);
157 if (unlikely(mf->read_pos + mf->offset == UINT32_MAX))
162 /// When flushing, we cannot run the match finder unless there is nice_len
163 /// bytes available in the dictionary. Instead, we skip running the match
164 /// finder (indicating that no match was found), and count how many bytes we
165 /// have ignored this way.
167 /// When new data is given after the flushing was completed, the match finder
168 /// is restarted by rewinding mf->read_pos backwards by mf->pending. Then
169 /// the missed bytes are added to the hash using the match finder's skip
170 /// function (with small amount of input, it may start using mf->pending
171 /// again if flushing).
173 /// Due to this rewinding, we don't touch cyclic_pos or test for
174 /// normalization. It will be done when the match finder's skip function
175 /// catches up after a flush.
177 move_pending(lzma_mf *mf)
180 assert(mf->read_pos <= mf->write_pos);
185 /// Calculate len_limit and determine if there is enough input to run
186 /// the actual match finder code. Sets up "cur" and "pos". This macro
187 /// is used by all find functions and binary tree skip functions. Hash
188 /// chain skip function doesn't need len_limit so a simpler code is used
190 #define header(is_bt, len_min, ret_op) \
191 uint32_t len_limit = mf_avail(mf); \
192 if (mf->nice_len <= len_limit) { \
193 len_limit = mf->nice_len; \
194 } else if (len_limit < (len_min) \
195 || (is_bt && mf->action == LZMA_SYNC_FLUSH)) { \
196 assert(mf->action != LZMA_RUN); \
200 const uint8_t *cur = mf_ptr(mf); \
201 const uint32_t pos = mf->read_pos + mf->offset
204 /// Header for find functions. "return 0" indicates that zero matches
206 #define header_find(is_bt, len_min) \
207 header(is_bt, len_min, return 0); \
208 uint32_t matches_count = 0
211 /// Header for a loop in a skip function. "continue" tells to skip the rest
212 /// of the code in the loop.
213 #define header_skip(is_bt, len_min) \
214 header(is_bt, len_min, continue)
217 /// Calls hc_find_func() or bt_find_func() and calculates the total number
218 /// of matches found. Updates the dictionary position and returns the number
219 /// of matches found.
220 #define call_find(func, len_best) \
222 matches_count = func(len_limit, pos, cur, cur_match, mf->depth, \
223 mf->son, mf->cyclic_pos, mf->cyclic_size, \
224 matches + matches_count, len_best) \
227 return matches_count; \
235 #if defined(HAVE_MF_HC3) || defined(HAVE_MF_HC4)
238 /// \param len_limit Don't look for matches longer than len_limit.
239 /// \param pos lzma_mf.read_pos + lzma_mf.offset
240 /// \param cur Pointer to current byte (mf_ptr(mf))
241 /// \param cur_match Start position of the current match candidate
242 /// \param depth Maximum length of the hash chain
243 /// \param son lzma_mf.son (contains the hash chain)
244 /// \param cyclic_pos
245 /// \param cyclic_size
246 /// \param matches Array to hold the matches.
247 /// \param len_best The length of the longest match found so far.
250 const uint32_t len_limit,
252 const uint8_t *const cur,
256 const uint32_t cyclic_pos,
257 const uint32_t cyclic_size,
261 son[cyclic_pos] = cur_match;
264 const uint32_t delta = pos - cur_match;
265 if (depth-- == 0 || delta >= cyclic_size)
268 const uint8_t *const pb = cur - delta;
269 cur_match = son[cyclic_pos - delta
270 + (delta > cyclic_pos ? cyclic_size : 0)];
272 if (pb[len_best] == cur[len_best] && pb[0] == cur[0]) {
274 while (++len != len_limit)
275 if (pb[len] != cur[len])
278 if (len_best < len) {
281 matches->dist = delta - 1;
284 if (len == len_limit)
292 #define hc_find(len_best) \
293 call_find(hc_find_func, len_best)
298 mf->son[mf->cyclic_pos] = cur_match; \
307 lzma_mf_hc3_find(lzma_mf *mf, lzma_match *matches)
309 header_find(false, 3);
313 const uint32_t delta2 = pos - mf->hash[hash_2_value];
314 const uint32_t cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value];
316 mf->hash[hash_2_value] = pos;
317 mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
319 uint32_t len_best = 2;
321 if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
322 for ( ; len_best != len_limit; ++len_best)
323 if (*(cur + len_best - delta2) != cur[len_best])
326 matches[0].len = len_best;
327 matches[0].dist = delta2 - 1;
330 if (len_best == len_limit) {
332 return 1; // matches_count
341 lzma_mf_hc3_skip(lzma_mf *mf, uint32_t amount)
344 if (mf_avail(mf) < 3) {
349 const uint8_t *cur = mf_ptr(mf);
350 const uint32_t pos = mf->read_pos + mf->offset;
354 const uint32_t cur_match
355 = mf->hash[FIX_3_HASH_SIZE + hash_value];
357 mf->hash[hash_2_value] = pos;
358 mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
362 } while (--amount != 0);
369 lzma_mf_hc4_find(lzma_mf *mf, lzma_match *matches)
371 header_find(false, 4);
375 uint32_t delta2 = pos - mf->hash[hash_2_value];
376 const uint32_t delta3
377 = pos - mf->hash[FIX_3_HASH_SIZE + hash_3_value];
378 const uint32_t cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value];
380 mf->hash[hash_2_value ] = pos;
381 mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
382 mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
384 uint32_t len_best = 1;
386 if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
389 matches[0].dist = delta2 - 1;
393 if (delta2 != delta3 && delta3 < mf->cyclic_size
394 && *(cur - delta3) == *cur) {
396 matches[matches_count++].dist = delta3 - 1;
400 if (matches_count != 0) {
401 for ( ; len_best != len_limit; ++len_best)
402 if (*(cur + len_best - delta2) != cur[len_best])
405 matches[matches_count - 1].len = len_best;
407 if (len_best == len_limit) {
409 return matches_count;
421 lzma_mf_hc4_skip(lzma_mf *mf, uint32_t amount)
424 if (mf_avail(mf) < 4) {
429 const uint8_t *cur = mf_ptr(mf);
430 const uint32_t pos = mf->read_pos + mf->offset;
434 const uint32_t cur_match
435 = mf->hash[FIX_4_HASH_SIZE + hash_value];
437 mf->hash[hash_2_value] = pos;
438 mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
439 mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
443 } while (--amount != 0);
452 #if defined(HAVE_MF_BT2) || defined(HAVE_MF_BT3) || defined(HAVE_MF_BT4)
455 const uint32_t len_limit,
457 const uint8_t *const cur,
461 const uint32_t cyclic_pos,
462 const uint32_t cyclic_size,
466 uint32_t *ptr0 = son + (cyclic_pos << 1) + 1;
467 uint32_t *ptr1 = son + (cyclic_pos << 1);
473 const uint32_t delta = pos - cur_match;
474 if (depth-- == 0 || delta >= cyclic_size) {
475 *ptr0 = EMPTY_HASH_VALUE;
476 *ptr1 = EMPTY_HASH_VALUE;
480 uint32_t *const pair = son + ((cyclic_pos - delta
481 + (delta > cyclic_pos ? cyclic_size : 0))
484 const uint8_t *const pb = cur - delta;
485 uint32_t len = my_min(len0, len1);
487 if (pb[len] == cur[len]) {
488 while (++len != len_limit)
489 if (pb[len] != cur[len])
492 if (len_best < len) {
495 matches->dist = delta - 1;
498 if (len == len_limit) {
506 if (pb[len] < cur[len]) {
523 const uint32_t len_limit,
525 const uint8_t *const cur,
529 const uint32_t cyclic_pos,
530 const uint32_t cyclic_size)
532 uint32_t *ptr0 = son + (cyclic_pos << 1) + 1;
533 uint32_t *ptr1 = son + (cyclic_pos << 1);
539 const uint32_t delta = pos - cur_match;
540 if (depth-- == 0 || delta >= cyclic_size) {
541 *ptr0 = EMPTY_HASH_VALUE;
542 *ptr1 = EMPTY_HASH_VALUE;
546 uint32_t *pair = son + ((cyclic_pos - delta
547 + (delta > cyclic_pos ? cyclic_size : 0))
549 const uint8_t *pb = cur - delta;
550 uint32_t len = my_min(len0, len1);
552 if (pb[len] == cur[len]) {
553 while (++len != len_limit)
554 if (pb[len] != cur[len])
557 if (len == len_limit) {
564 if (pb[len] < cur[len]) {
579 #define bt_find(len_best) \
580 call_find(bt_find_func, len_best)
584 bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, \
585 mf->son, mf->cyclic_pos, \
595 lzma_mf_bt2_find(lzma_mf *mf, lzma_match *matches)
597 header_find(true, 2);
601 const uint32_t cur_match = mf->hash[hash_value];
602 mf->hash[hash_value] = pos;
609 lzma_mf_bt2_skip(lzma_mf *mf, uint32_t amount)
612 header_skip(true, 2);
616 const uint32_t cur_match = mf->hash[hash_value];
617 mf->hash[hash_value] = pos;
621 } while (--amount != 0);
628 lzma_mf_bt3_find(lzma_mf *mf, lzma_match *matches)
630 header_find(true, 3);
634 const uint32_t delta2 = pos - mf->hash[hash_2_value];
635 const uint32_t cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value];
637 mf->hash[hash_2_value] = pos;
638 mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
640 uint32_t len_best = 2;
642 if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
643 for ( ; len_best != len_limit; ++len_best)
644 if (*(cur + len_best - delta2) != cur[len_best])
647 matches[0].len = len_best;
648 matches[0].dist = delta2 - 1;
651 if (len_best == len_limit) {
653 return 1; // matches_count
662 lzma_mf_bt3_skip(lzma_mf *mf, uint32_t amount)
665 header_skip(true, 3);
669 const uint32_t cur_match
670 = mf->hash[FIX_3_HASH_SIZE + hash_value];
672 mf->hash[hash_2_value] = pos;
673 mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
677 } while (--amount != 0);
684 lzma_mf_bt4_find(lzma_mf *mf, lzma_match *matches)
686 header_find(true, 4);
690 uint32_t delta2 = pos - mf->hash[hash_2_value];
691 const uint32_t delta3
692 = pos - mf->hash[FIX_3_HASH_SIZE + hash_3_value];
693 const uint32_t cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value];
695 mf->hash[hash_2_value] = pos;
696 mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
697 mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
699 uint32_t len_best = 1;
701 if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
704 matches[0].dist = delta2 - 1;
708 if (delta2 != delta3 && delta3 < mf->cyclic_size
709 && *(cur - delta3) == *cur) {
711 matches[matches_count++].dist = delta3 - 1;
715 if (matches_count != 0) {
716 for ( ; len_best != len_limit; ++len_best)
717 if (*(cur + len_best - delta2) != cur[len_best])
720 matches[matches_count - 1].len = len_best;
722 if (len_best == len_limit) {
724 return matches_count;
736 lzma_mf_bt4_skip(lzma_mf *mf, uint32_t amount)
739 header_skip(true, 4);
743 const uint32_t cur_match
744 = mf->hash[FIX_4_HASH_SIZE + hash_value];
746 mf->hash[hash_2_value] = pos;
747 mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
748 mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
752 } while (--amount != 0);