- u32 num_passes_remaining = c->params.num_optim_passes;
- const u8 *window_ptr;
- const u8 *window_end;
- struct xpress_item *next_chosen_item;
- struct lz_match raw_item;
- struct xpress_item xpress_item;
-
- if (c->params.choose_item_func == xpress_choose_near_optimal_item) {
- xpress_set_default_costs(c->costs);
- c->optimum_cur_idx = 0;
- c->optimum_end_idx = 0;
- } else {
- c->prev_match.len = 0;
- if (c->cur_window_size <= 8192)
- c->len_3_too_far = 2048;
- else
- c->len_3_too_far = 4096;
- }
-
- if (c->params.num_optim_passes > 1) {
- c->get_matches_func = xpress_get_matches_fillcache;
- c->skip_bytes_func = xpress_skip_bytes_fillcache;
- } else {
- c->get_matches_func = xpress_get_matches_noncaching;
- c->skip_bytes_func = xpress_skip_bytes_noncaching;
- }
-
- lz_mf_load_window(c->mf, c->cur_window, c->cur_window_size);
-
- while (--num_passes_remaining) {
- window_ptr = c->cur_window_ptr = c->cur_window;
- window_end = window_ptr + c->cur_window_size;
- c->cache_ptr = c->cached_matches;
- memset(c->freqs, 0, sizeof(c->freqs));
-
- while (window_ptr != window_end) {
- raw_item = xpress_choose_item(c);
- if (raw_item.len >= XPRESS_MIN_MATCH_LEN) {
- xpress_tally_match(raw_item.len,
- raw_item.offset, c->freqs);
- window_ptr += raw_item.len;
- } else {
- xpress_tally_literal(*window_ptr, c->freqs);
- window_ptr += 1;
- }
- }
- c->freqs[XPRESS_END_OF_DATA]++;
- xpress_make_huffman_code(c);
- xpress_set_costs(c->costs, c->lens);
- if (c->cache_ptr <= c->cache_limit) {
- c->get_matches_func = xpress_get_matches_usecache_nocheck;
- c->skip_bytes_func = xpress_skip_bytes_usecache_nocheck;
- } else {
- c->get_matches_func = xpress_get_matches_usecache;
- c->skip_bytes_func = xpress_skip_bytes_usecache;
- }
- }
-
- window_ptr = c->cur_window_ptr = c->cur_window;
- window_end = window_ptr + c->cur_window_size;
- c->cache_ptr = c->cached_matches;
- memset(c->freqs, 0, sizeof(c->freqs));
- next_chosen_item = c->chosen_items;
-
- u32 unseen_cost = 9;
- while (window_ptr != window_end) {
- raw_item = xpress_choose_item(c);
- if (raw_item.len >= XPRESS_MIN_MATCH_LEN) {
- xpress_item = xpress_tally_match(raw_item.len,
- raw_item.offset,
- c->freqs);
- window_ptr += raw_item.len;
- } else {
- xpress_item = xpress_tally_literal(*window_ptr,
- c->freqs);
- window_ptr += 1;
- }
- *next_chosen_item++ = xpress_item;
-
- /* When doing one-pass near-optimal parsing, rebuild the Huffman
- * code occasionally. */
- if (unlikely((next_chosen_item - c->chosen_items) % 2048 == 0) &&
- c->params.choose_item_func == xpress_choose_near_optimal_item &&
- c->cur_window_size >= 16384 &&
- c->params.num_optim_passes == 1)
- {
- xpress_make_huffman_code(c);
- for (unsigned i = 0; i < XPRESS_NUM_SYMBOLS; i++)
- c->costs[i] = c->lens[i] ? c->lens[i] : unseen_cost;
- if (unseen_cost < 15)
- unseen_cost++;
- }
- }
- c->freqs[XPRESS_END_OF_DATA]++;
- xpress_make_huffman_code(c);
- return next_chosen_item - c->chosen_items;