xz: Use the info collected in parse_block_list()

This is slightly simpler and it avoids looping through
the opt_block_list array.
This commit is contained in:
Lasse Collin 2024-05-12 16:28:25 +03:00
parent 81d350dab8
commit 8fac2577f2
1 changed files with 37 additions and 54 deletions

View File

@ -11,6 +11,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#include "private.h" #include "private.h"
#include "tuklib_integer.h"
/// Return value type for coder_init(). /// Return value type for coder_init().
@ -230,19 +231,6 @@ memlimit_too_small(uint64_t memory_usage)
#ifdef HAVE_ENCODERS #ifdef HAVE_ENCODERS
// For a given opt_block_list index, validate that the filter has been
// set. If it has not been set, we must exit with error to avoid using
// an uninitialized filter chain.
static void
validate_block_list_filter(const uint32_t filter_num)
{
if (!(filters_used_mask & (1U << filter_num)))
message_fatal(_("filter chain %u used by --block-list but "
"not specified with --filters%u="),
(unsigned)filter_num, (unsigned)filter_num);
}
// Calculate the memory usage of each filter chain. // Calculate the memory usage of each filter chain.
// Return the maximum memory usage of all of the filter chains. // Return the maximum memory usage of all of the filter chains.
static uint64_t static uint64_t
@ -302,48 +290,43 @@ coder_set_compression_settings(void)
#endif #endif
#ifdef HAVE_ENCODERS #ifdef HAVE_ENCODERS
# ifdef MYTHREAD_ENABLED
// Represents the largest Block size specified with --block-list. This
// is needed to help reduce the Block size in the multithreaded encoder
// so memory is not wasted.
uint64_t max_block_list_size = 0;
# endif
if (opt_block_list != NULL) { if (opt_block_list != NULL) {
// This mask tracks the filters actually referenced in // Find out if block_list_chain_mask has a bit set that
// --block-list. It is used to help remove bits from // isn't set in filters_used_mask.
// filters_used_mask when a filter chain was specified const uint32_t missing_chains_mask
// but never actually used. = (block_list_chain_mask ^ filters_used_mask)
uint32_t filters_ref_mask = 0; & block_list_chain_mask;
for (uint32_t i = 0; opt_block_list[i].size != 0; i++) { // If a filter chain was specified in --block-list but no
validate_block_list_filter( // matching --filtersX option was used, exit with an error.
opt_block_list[i].filters_index); if (missing_chains_mask != 0) {
// Get the number of the first missing filter chain
// and show it in the error message.
const unsigned first_missing
= (unsigned)ctz32(missing_chains_mask);
// Mark the current filter as referenced. message_fatal(_("filter chain %u used by "
filters_ref_mask |= 1U << "--block-list but not specified "
opt_block_list[i].filters_index; "with --filters%u="),
first_missing, first_missing);
# ifdef MYTHREAD_ENABLED
if (opt_block_list[i].size > max_block_list_size)
max_block_list_size = opt_block_list[i].size;
# endif
} }
assert(filters_ref_mask != 0); // Omit the unused filter chains from mask of used chains.
//
// NOTE: The filters that were initialized but not used do // (FIXME? When built with debugging, coder_free() will free()
// not free their options and do not have the filter // the filter chains (except the default chain) which makes
// IDs set to LZMA_VLI_UNKNOWN. Filter chains are not // Valgrind show fewer reachable allocations. But coder_free()
// freed outside of debug mode and the default filter // uses this mask to determine which chains to free. Thus it
// chain is never freed. // won't free the ones that are cleared here from the mask.
filters_used_mask = filters_ref_mask; // In practice this doesn't matter.)
filters_used_mask &= block_list_chain_mask;
} else { } else {
// Reset filters used mask in case --block-list is not // Reset filters used mask in case --block-list is not
// used, but --filtersX is used. // used, but --filtersX is used.
filters_used_mask = 1U << 0; filters_used_mask = 1U << 0;
} }
#endif #endif
// The default check type is CRC64, but fallback to CRC32 // The default check type is CRC64, but fallback to CRC32
// if CRC64 isn't supported by the copy of liblzma we are // if CRC64 isn't supported by the copy of liblzma we are
// using. CRC32 is always supported. // using. CRC32 is always supported.
@ -496,16 +479,16 @@ coder_set_compression_settings(void)
block_size = size; block_size = size;
} }
// If the largest block size specified // If --block-list was used and our current
// with --block-list is less than the // Block size exceeds the largest size
// recommended Block size, then it is a waste // in --block-list, reduce the Block size of
// of RAM to use a larger Block size. It may // the multithreaded encoder. The extra size
// even allow more threads to be used in some // would only be a waste of RAM. With a
// situations. // smaller Block size we might even be able
if (max_block_list_size > 0 // to use more threads in some cases.
&& max_block_list_size if (block_list_largest > 0 && block_size
< block_size) > block_list_largest)
block_size = max_block_list_size; block_size = block_list_largest;
} }
mt_options.block_size = block_size; mt_options.block_size = block_size;