1 /////////////////////////////////////////////////////////////////////////////// 2 // 3 /// \file lz_encoder_mf.c 4 /// \brief Match finders 5 /// 6 // Authors: Igor Pavlov 7 // Lasse Collin 8 // 9 // This file has been put into the public domain. 10 // You can do whatever you want with this file. 11 // 12 /////////////////////////////////////////////////////////////////////////////// 13 14 #include "lz_encoder.h" 15 #include "lz_encoder_hash.h" 16 #include "memcmplen.h" 17 18 19 /// \brief Find matches starting from the current byte 20 /// 21 /// \return The length of the longest match found 22 extern uint32_t 23 lzma_mf_find(lzma_mf *mf, uint32_t *count_ptr, lzma_match *matches) 24 { 25 // Call the match finder. It returns the number of length-distance 26 // pairs found. 27 // FIXME: Minimum count is zero, what _exactly_ is the maximum? 28 const uint32_t count = mf->find(mf, matches); 29 30 // Length of the longest match; assume that no matches were found 31 // and thus the maximum length is zero. 32 uint32_t len_best = 0; 33 34 if (count > 0) { 35 #ifndef NDEBUG 36 // Validate the matches. 37 for (uint32_t i = 0; i < count; ++i) { 38 assert(matches[i].len <= mf->nice_len); 39 assert(matches[i].dist < mf->read_pos); 40 assert(memcmp(mf_ptr(mf) - 1, 41 mf_ptr(mf) - matches[i].dist - 2, 42 matches[i].len) == 0); 43 } 44 #endif 45 46 // The last used element in the array contains 47 // the longest match. 48 len_best = matches[count - 1].len; 49 50 // If a match of maximum search length was found, try to 51 // extend the match to maximum possible length. 52 if (len_best == mf->nice_len) { 53 // The limit for the match length is either the 54 // maximum match length supported by the LZ-based 55 // encoder or the number of bytes left in the 56 // dictionary, whichever is smaller. 57 uint32_t limit = mf_avail(mf) + 1; 58 if (limit > mf->match_len_max) 59 limit = mf->match_len_max; 60 61 // Pointer to the byte we just ran through 62 // the match finder. 63 const uint8_t *p1 = mf_ptr(mf) - 1; 64 65 // Pointer to the beginning of the match. We need -1 66 // here because the match distances are zero based. 67 const uint8_t *p2 = p1 - matches[count - 1].dist - 1; 68 69 len_best = lzma_memcmplen(p1, p2, len_best, limit); 70 } 71 } 72 73 *count_ptr = count; 74 75 // Finally update the read position to indicate that match finder was 76 // run for this dictionary offset. 77 ++mf->read_ahead; 78 79 return len_best; 80 } 81 82 83 /// Hash value to indicate unused element in the hash. Since we start the 84 /// positions from dict_size + 1, zero is always too far to qualify 85 /// as usable match position. 86 #define EMPTY_HASH_VALUE 0 87 88 89 /// Normalization must be done when lzma_mf.offset + lzma_mf.read_pos 90 /// reaches MUST_NORMALIZE_POS. 91 #define MUST_NORMALIZE_POS UINT32_MAX 92 93 94 /// \brief Normalizes hash values 95 /// 96 /// The hash arrays store positions of match candidates. The positions are 97 /// relative to an arbitrary offset that is not the same as the absolute 98 /// offset in the input stream. The relative position of the current byte 99 /// is lzma_mf.offset + lzma_mf.read_pos. The distances of the matches are 100 /// the differences of the current read position and the position found from 101 /// the hash. 102 /// 103 /// To prevent integer overflows of the offsets stored in the hash arrays, 104 /// we need to "normalize" the stored values now and then. During the 105 /// normalization, we drop values that indicate distance greater than the 106 /// dictionary size, thus making space for new values. 107 static void 108 normalize(lzma_mf *mf) 109 { 110 assert(mf->read_pos + mf->offset == MUST_NORMALIZE_POS); 111 112 // In future we may not want to touch the lowest bits, because there 113 // may be match finders that use larger resolution than one byte. 114 const uint32_t subvalue 115 = (MUST_NORMALIZE_POS - mf->cyclic_size); 116 // & ~((UINT32_C(1) << 10) - 1); 117 118 for (uint32_t i = 0; i < mf->hash_count; ++i) { 119 // If the distance is greater than the dictionary size, 120 // we can simply mark the hash element as empty. 121 if (mf->hash[i] <= subvalue) 122 mf->hash[i] = EMPTY_HASH_VALUE; 123 else 124 mf->hash[i] -= subvalue; 125 } 126 127 for (uint32_t i = 0; i < mf->sons_count; ++i) { 128 // Do the same for mf->son. 129 // 130 // NOTE: There may be uninitialized elements in mf->son. 131 // Valgrind may complain that the "if" below depends on 132 // an uninitialized value. In this case it is safe to ignore 133 // the warning. See also the comments in lz_encoder_init() 134 // in lz_encoder.c. 135 if (mf->son[i] <= subvalue) 136 mf->son[i] = EMPTY_HASH_VALUE; 137 else 138 mf->son[i] -= subvalue; 139 } 140 141 // Update offset to match the new locations. 142 mf->offset -= subvalue; 143 144 return; 145 } 146 147 148 /// Mark the current byte as processed from point of view of the match finder. 149 static void 150 move_pos(lzma_mf *mf) 151 { 152 if (++mf->cyclic_pos == mf->cyclic_size) 153 mf->cyclic_pos = 0; 154 155 ++mf->read_pos; 156 assert(mf->read_pos <= mf->write_pos); 157 158 if (unlikely(mf->read_pos + mf->offset == UINT32_MAX)) 159 normalize(mf); 160 } 161 162 163 /// When flushing, we cannot run the match finder unless there is nice_len 164 /// bytes available in the dictionary. Instead, we skip running the match 165 /// finder (indicating that no match was found), and count how many bytes we 166 /// have ignored this way. 167 /// 168 /// When new data is given after the flushing was completed, the match finder 169 /// is restarted by rewinding mf->read_pos backwards by mf->pending. Then 170 /// the missed bytes are added to the hash using the match finder's skip 171 /// function (with small amount of input, it may start using mf->pending 172 /// again if flushing). 173 /// 174 /// Due to this rewinding, we don't touch cyclic_pos or test for 175 /// normalization. It will be done when the match finder's skip function 176 /// catches up after a flush. 177 static void 178 move_pending(lzma_mf *mf) 179 { 180 ++mf->read_pos; 181 assert(mf->read_pos <= mf->write_pos); 182 ++mf->pending; 183 } 184 185 186 /// Calculate len_limit and determine if there is enough input to run 187 /// the actual match finder code. Sets up "cur" and "pos". This macro 188 /// is used by all find functions and binary tree skip functions. Hash 189 /// chain skip function doesn't need len_limit so a simpler code is used 190 /// in them. 191 #define header(is_bt, len_min, ret_op) \ 192 uint32_t len_limit = mf_avail(mf); \ 193 if (mf->nice_len <= len_limit) { \ 194 len_limit = mf->nice_len; \ 195 } else if (len_limit < (len_min) \ 196 || (is_bt && mf->action == LZMA_SYNC_FLUSH)) { \ 197 assert(mf->action != LZMA_RUN); \ 198 move_pending(mf); \ 199 ret_op; \ 200 } \ 201 const uint8_t *cur = mf_ptr(mf); \ 202 const uint32_t pos = mf->read_pos + mf->offset 203 204 205 /// Header for find functions. "return 0" indicates that zero matches 206 /// were found. 207 #define header_find(is_bt, len_min) \ 208 header(is_bt, len_min, return 0); \ 209 uint32_t matches_count = 0 210 211 212 /// Header for a loop in a skip function. "continue" tells to skip the rest 213 /// of the code in the loop. 214 #define header_skip(is_bt, len_min) \ 215 header(is_bt, len_min, continue) 216 217 218 /// Calls hc_find_func() or bt_find_func() and calculates the total number 219 /// of matches found. Updates the dictionary position and returns the number 220 /// of matches found. 221 #define call_find(func, len_best) \ 222 do { \ 223 matches_count = (uint32_t)(func(len_limit, pos, cur, cur_match, \ 224 mf->depth, mf->son, \ 225 mf->cyclic_pos, mf->cyclic_size, \ 226 matches + matches_count, len_best) \ 227 - matches); \ 228 move_pos(mf); \ 229 return matches_count; \ 230 } while (0) 231 232 233 //////////////// 234 // Hash Chain // 235 //////////////// 236 237 #if defined(HAVE_MF_HC3) || defined(HAVE_MF_HC4) 238 /// 239 /// 240 /// \param len_limit Don't look for matches longer than len_limit. 241 /// \param pos lzma_mf.read_pos + lzma_mf.offset 242 /// \param cur Pointer to current byte (mf_ptr(mf)) 243 /// \param cur_match Start position of the current match candidate 244 /// \param depth Maximum length of the hash chain 245 /// \param son lzma_mf.son (contains the hash chain) 246 /// \param cyclic_pos lzma_mf.cyclic_pos 247 /// \param cyclic_size lzma_mf_cyclic_size 248 /// \param matches Array to hold the matches. 249 /// \param len_best The length of the longest match found so far. 250 static lzma_match * 251 hc_find_func( 252 const uint32_t len_limit, 253 const uint32_t pos, 254 const uint8_t *const cur, 255 uint32_t cur_match, 256 uint32_t depth, 257 uint32_t *const son, 258 const uint32_t cyclic_pos, 259 const uint32_t cyclic_size, 260 lzma_match *matches, 261 uint32_t len_best) 262 { 263 son[cyclic_pos] = cur_match; 264 265 while (true) { 266 const uint32_t delta = pos - cur_match; 267 if (depth-- == 0 || delta >= cyclic_size) 268 return matches; 269 270 const uint8_t *const pb = cur - delta; 271 cur_match = son[cyclic_pos - delta 272 + (delta > cyclic_pos ? cyclic_size : 0)]; 273 274 if (pb[len_best] == cur[len_best] && pb[0] == cur[0]) { 275 uint32_t len = lzma_memcmplen(pb, cur, 1, len_limit); 276 277 if (len_best < len) { 278 len_best = len; 279 matches->len = len; 280 matches->dist = delta - 1; 281 ++matches; 282 283 if (len == len_limit) 284 return matches; 285 } 286 } 287 } 288 } 289 290 291 #define hc_find(len_best) \ 292 call_find(hc_find_func, len_best) 293 294 295 #define hc_skip() \ 296 do { \ 297 mf->son[mf->cyclic_pos] = cur_match; \ 298 move_pos(mf); \ 299 } while (0) 300 301 #endif 302 303 304 #ifdef HAVE_MF_HC3 305 extern uint32_t 306 lzma_mf_hc3_find(lzma_mf *mf, lzma_match *matches) 307 { 308 header_find(false, 3); 309 310 hash_3_calc(); 311 312 const uint32_t delta2 = pos - mf->hash[hash_2_value]; 313 const uint32_t cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value]; 314 315 mf->hash[hash_2_value] = pos; 316 mf->hash[FIX_3_HASH_SIZE + hash_value] = pos; 317 318 uint32_t len_best = 2; 319 320 if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { 321 len_best = lzma_memcmplen(cur - delta2, cur, 322 len_best, len_limit); 323 324 matches[0].len = len_best; 325 matches[0].dist = delta2 - 1; 326 matches_count = 1; 327 328 if (len_best == len_limit) { 329 hc_skip(); 330 return 1; // matches_count 331 } 332 } 333 334 hc_find(len_best); 335 } 336 337 338 extern void 339 lzma_mf_hc3_skip(lzma_mf *mf, uint32_t amount) 340 { 341 do { 342 if (mf_avail(mf) < 3) { 343 move_pending(mf); 344 continue; 345 } 346 347 const uint8_t *cur = mf_ptr(mf); 348 const uint32_t pos = mf->read_pos + mf->offset; 349 350 hash_3_calc(); 351 352 const uint32_t cur_match 353 = mf->hash[FIX_3_HASH_SIZE + hash_value]; 354 355 mf->hash[hash_2_value] = pos; 356 mf->hash[FIX_3_HASH_SIZE + hash_value] = pos; 357 358 hc_skip(); 359 360 } while (--amount != 0); 361 } 362 #endif 363 364 365 #ifdef HAVE_MF_HC4 366 extern uint32_t 367 lzma_mf_hc4_find(lzma_mf *mf, lzma_match *matches) 368 { 369 header_find(false, 4); 370 371 hash_4_calc(); 372 373 uint32_t delta2 = pos - mf->hash[hash_2_value]; 374 const uint32_t delta3 375 = pos - mf->hash[FIX_3_HASH_SIZE + hash_3_value]; 376 const uint32_t cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value]; 377 378 mf->hash[hash_2_value ] = pos; 379 mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos; 380 mf->hash[FIX_4_HASH_SIZE + hash_value] = pos; 381 382 uint32_t len_best = 1; 383 384 if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { 385 len_best = 2; 386 matches[0].len = 2; 387 matches[0].dist = delta2 - 1; 388 matches_count = 1; 389 } 390 391 if (delta2 != delta3 && delta3 < mf->cyclic_size 392 && *(cur - delta3) == *cur) { 393 len_best = 3; 394 matches[matches_count++].dist = delta3 - 1; 395 delta2 = delta3; 396 } 397 398 if (matches_count != 0) { 399 len_best = lzma_memcmplen(cur - delta2, cur, 400 len_best, len_limit); 401 402 matches[matches_count - 1].len = len_best; 403 404 if (len_best == len_limit) { 405 hc_skip(); 406 return matches_count; 407 } 408 } 409 410 if (len_best < 3) 411 len_best = 3; 412 413 hc_find(len_best); 414 } 415 416 417 extern void 418 lzma_mf_hc4_skip(lzma_mf *mf, uint32_t amount) 419 { 420 do { 421 if (mf_avail(mf) < 4) { 422 move_pending(mf); 423 continue; 424 } 425 426 const uint8_t *cur = mf_ptr(mf); 427 const uint32_t pos = mf->read_pos + mf->offset; 428 429 hash_4_calc(); 430 431 const uint32_t cur_match 432 = mf->hash[FIX_4_HASH_SIZE + hash_value]; 433 434 mf->hash[hash_2_value] = pos; 435 mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos; 436 mf->hash[FIX_4_HASH_SIZE + hash_value] = pos; 437 438 hc_skip(); 439 440 } while (--amount != 0); 441 } 442 #endif 443 444 445 ///////////////// 446 // Binary Tree // 447 ///////////////// 448 449 #if defined(HAVE_MF_BT2) || defined(HAVE_MF_BT3) || defined(HAVE_MF_BT4) 450 static lzma_match * 451 bt_find_func( 452 const uint32_t len_limit, 453 const uint32_t pos, 454 const uint8_t *const cur, 455 uint32_t cur_match, 456 uint32_t depth, 457 uint32_t *const son, 458 const uint32_t cyclic_pos, 459 const uint32_t cyclic_size, 460 lzma_match *matches, 461 uint32_t len_best) 462 { 463 uint32_t *ptr0 = son + (cyclic_pos << 1) + 1; 464 uint32_t *ptr1 = son + (cyclic_pos << 1); 465 466 uint32_t len0 = 0; 467 uint32_t len1 = 0; 468 469 while (true) { 470 const uint32_t delta = pos - cur_match; 471 if (depth-- == 0 || delta >= cyclic_size) { 472 *ptr0 = EMPTY_HASH_VALUE; 473 *ptr1 = EMPTY_HASH_VALUE; 474 return matches; 475 } 476 477 uint32_t *const pair = son + ((cyclic_pos - delta 478 + (delta > cyclic_pos ? cyclic_size : 0)) 479 << 1); 480 481 const uint8_t *const pb = cur - delta; 482 uint32_t len = my_min(len0, len1); 483 484 if (pb[len] == cur[len]) { 485 len = lzma_memcmplen(pb, cur, len + 1, len_limit); 486 487 if (len_best < len) { 488 len_best = len; 489 matches->len = len; 490 matches->dist = delta - 1; 491 ++matches; 492 493 if (len == len_limit) { 494 *ptr1 = pair[0]; 495 *ptr0 = pair[1]; 496 return matches; 497 } 498 } 499 } 500 501 if (pb[len] < cur[len]) { 502 *ptr1 = cur_match; 503 ptr1 = pair + 1; 504 cur_match = *ptr1; 505 len1 = len; 506 } else { 507 *ptr0 = cur_match; 508 ptr0 = pair; 509 cur_match = *ptr0; 510 len0 = len; 511 } 512 } 513 } 514 515 516 static void 517 bt_skip_func( 518 const uint32_t len_limit, 519 const uint32_t pos, 520 const uint8_t *const cur, 521 uint32_t cur_match, 522 uint32_t depth, 523 uint32_t *const son, 524 const uint32_t cyclic_pos, 525 const uint32_t cyclic_size) 526 { 527 uint32_t *ptr0 = son + (cyclic_pos << 1) + 1; 528 uint32_t *ptr1 = son + (cyclic_pos << 1); 529 530 uint32_t len0 = 0; 531 uint32_t len1 = 0; 532 533 while (true) { 534 const uint32_t delta = pos - cur_match; 535 if (depth-- == 0 || delta >= cyclic_size) { 536 *ptr0 = EMPTY_HASH_VALUE; 537 *ptr1 = EMPTY_HASH_VALUE; 538 return; 539 } 540 541 uint32_t *pair = son + ((cyclic_pos - delta 542 + (delta > cyclic_pos ? cyclic_size : 0)) 543 << 1); 544 const uint8_t *pb = cur - delta; 545 uint32_t len = my_min(len0, len1); 546 547 if (pb[len] == cur[len]) { 548 len = lzma_memcmplen(pb, cur, len + 1, len_limit); 549 550 if (len == len_limit) { 551 *ptr1 = pair[0]; 552 *ptr0 = pair[1]; 553 return; 554 } 555 } 556 557 if (pb[len] < cur[len]) { 558 *ptr1 = cur_match; 559 ptr1 = pair + 1; 560 cur_match = *ptr1; 561 len1 = len; 562 } else { 563 *ptr0 = cur_match; 564 ptr0 = pair; 565 cur_match = *ptr0; 566 len0 = len; 567 } 568 } 569 } 570 571 572 #define bt_find(len_best) \ 573 call_find(bt_find_func, len_best) 574 575 #define bt_skip() \ 576 do { \ 577 bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, \ 578 mf->son, mf->cyclic_pos, \ 579 mf->cyclic_size); \ 580 move_pos(mf); \ 581 } while (0) 582 583 #endif 584 585 586 #ifdef HAVE_MF_BT2 587 extern uint32_t 588 lzma_mf_bt2_find(lzma_mf *mf, lzma_match *matches) 589 { 590 header_find(true, 2); 591 592 hash_2_calc(); 593 594 const uint32_t cur_match = mf->hash[hash_value]; 595 mf->hash[hash_value] = pos; 596 597 bt_find(1); 598 } 599 600 601 extern void 602 lzma_mf_bt2_skip(lzma_mf *mf, uint32_t amount) 603 { 604 do { 605 header_skip(true, 2); 606 607 hash_2_calc(); 608 609 const uint32_t cur_match = mf->hash[hash_value]; 610 mf->hash[hash_value] = pos; 611 612 bt_skip(); 613 614 } while (--amount != 0); 615 } 616 #endif 617 618 619 #ifdef HAVE_MF_BT3 620 extern uint32_t 621 lzma_mf_bt3_find(lzma_mf *mf, lzma_match *matches) 622 { 623 header_find(true, 3); 624 625 hash_3_calc(); 626 627 const uint32_t delta2 = pos - mf->hash[hash_2_value]; 628 const uint32_t cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value]; 629 630 mf->hash[hash_2_value] = pos; 631 mf->hash[FIX_3_HASH_SIZE + hash_value] = pos; 632 633 uint32_t len_best = 2; 634 635 if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { 636 len_best = lzma_memcmplen( 637 cur, cur - delta2, len_best, len_limit); 638 639 matches[0].len = len_best; 640 matches[0].dist = delta2 - 1; 641 matches_count = 1; 642 643 if (len_best == len_limit) { 644 bt_skip(); 645 return 1; // matches_count 646 } 647 } 648 649 bt_find(len_best); 650 } 651 652 653 extern void 654 lzma_mf_bt3_skip(lzma_mf *mf, uint32_t amount) 655 { 656 do { 657 header_skip(true, 3); 658 659 hash_3_calc(); 660 661 const uint32_t cur_match 662 = mf->hash[FIX_3_HASH_SIZE + hash_value]; 663 664 mf->hash[hash_2_value] = pos; 665 mf->hash[FIX_3_HASH_SIZE + hash_value] = pos; 666 667 bt_skip(); 668 669 } while (--amount != 0); 670 } 671 #endif 672 673 674 #ifdef HAVE_MF_BT4 675 extern uint32_t 676 lzma_mf_bt4_find(lzma_mf *mf, lzma_match *matches) 677 { 678 header_find(true, 4); 679 680 hash_4_calc(); 681 682 uint32_t delta2 = pos - mf->hash[hash_2_value]; 683 const uint32_t delta3 684 = pos - mf->hash[FIX_3_HASH_SIZE + hash_3_value]; 685 const uint32_t cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value]; 686 687 mf->hash[hash_2_value] = pos; 688 mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos; 689 mf->hash[FIX_4_HASH_SIZE + hash_value] = pos; 690 691 uint32_t len_best = 1; 692 693 if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { 694 len_best = 2; 695 matches[0].len = 2; 696 matches[0].dist = delta2 - 1; 697 matches_count = 1; 698 } 699 700 if (delta2 != delta3 && delta3 < mf->cyclic_size 701 && *(cur - delta3) == *cur) { 702 len_best = 3; 703 matches[matches_count++].dist = delta3 - 1; 704 delta2 = delta3; 705 } 706 707 if (matches_count != 0) { 708 len_best = lzma_memcmplen( 709 cur, cur - delta2, len_best, len_limit); 710 711 matches[matches_count - 1].len = len_best; 712 713 if (len_best == len_limit) { 714 bt_skip(); 715 return matches_count; 716 } 717 } 718 719 if (len_best < 3) 720 len_best = 3; 721 722 bt_find(len_best); 723 } 724 725 726 extern void 727 lzma_mf_bt4_skip(lzma_mf *mf, uint32_t amount) 728 { 729 do { 730 header_skip(true, 4); 731 732 hash_4_calc(); 733 734 const uint32_t cur_match 735 = mf->hash[FIX_4_HASH_SIZE + hash_value]; 736 737 mf->hash[hash_2_value] = pos; 738 mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos; 739 mf->hash[FIX_4_HASH_SIZE + hash_value] = pos; 740 741 bt_skip(); 742 743 } while (--amount != 0); 744 } 745 #endif 746