xz: Make --block-list and --block-size work together in single-threaded.
Previously, --block-list and --block-size only worked together in threaded mode. Boundaries are specified by --block-list, but --block-size specifies the maximum size for a Block. Now this works in single-threaded mode too. Thanks to James M Leddy for the original patch.
This commit is contained in:
parent
ae222fe980
commit
dd750acbe2
|
@ -514,6 +514,56 @@ coder_init(file_pair *pair)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Resolve conflicts between opt_block_size and opt_block_list in single
|
||||||
|
/// threaded mode. We want to default to opt_block_list, except when it is
|
||||||
|
/// larger than opt_block_size. If this is the case for the current Block
|
||||||
|
/// at *list_pos, then we break into smaller Blocks. Otherwise advance
|
||||||
|
/// to the next Block in opt_block_list, and break apart if needed.
|
||||||
|
static void
|
||||||
|
split_block(uint64_t *block_remaining,
|
||||||
|
uint64_t *next_block_remaining,
|
||||||
|
uint64_t *list_pos)
|
||||||
|
{
|
||||||
|
if (*next_block_remaining > 0) {
|
||||||
|
// The Block at *list_pos has previously been split up.
|
||||||
|
assert(hardware_threads_get() == 1);
|
||||||
|
assert(opt_block_size > 0);
|
||||||
|
assert(opt_block_list != NULL);
|
||||||
|
|
||||||
|
if (*next_block_remaining > opt_block_size) {
|
||||||
|
// We have to split the current Block at *list_pos
|
||||||
|
// into another opt_block_size length Block.
|
||||||
|
*block_remaining = opt_block_size;
|
||||||
|
} else {
|
||||||
|
// This is the last remaining split Block for the
|
||||||
|
// Block at *list_pos.
|
||||||
|
*block_remaining = *next_block_remaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
*next_block_remaining -= *block_remaining;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// The Block at *list_pos has been finished. Go to the next
|
||||||
|
// entry in the list. If the end of the list has been reached,
|
||||||
|
// reuse the size of the last Block.
|
||||||
|
if (opt_block_list[*list_pos + 1] != 0)
|
||||||
|
++*list_pos;
|
||||||
|
|
||||||
|
*block_remaining = opt_block_list[*list_pos];
|
||||||
|
|
||||||
|
// If in single-threaded mode, split up the Block if needed.
|
||||||
|
// This is not needed in multi-threaded mode because liblzma
|
||||||
|
// will do this due to how threaded encoding works.
|
||||||
|
if (hardware_threads_get() == 1 && opt_block_size > 0
|
||||||
|
&& *block_remaining > opt_block_size) {
|
||||||
|
*next_block_remaining
|
||||||
|
= *block_remaining - opt_block_size;
|
||||||
|
*block_remaining = opt_block_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Compress or decompress using liblzma.
|
/// Compress or decompress using liblzma.
|
||||||
static bool
|
static bool
|
||||||
coder_normal(file_pair *pair)
|
coder_normal(file_pair *pair)
|
||||||
|
@ -537,6 +587,10 @@ coder_normal(file_pair *pair)
|
||||||
// only a single block is created.
|
// only a single block is created.
|
||||||
uint64_t block_remaining = UINT64_MAX;
|
uint64_t block_remaining = UINT64_MAX;
|
||||||
|
|
||||||
|
// next_block_remining for when we are in single-threaded mode and
|
||||||
|
// the Block in --block-list is larger than the --block-size=SIZE.
|
||||||
|
uint64_t next_block_remaining = 0;
|
||||||
|
|
||||||
// Position in opt_block_list. Unused if --block-list wasn't used.
|
// Position in opt_block_list. Unused if --block-list wasn't used.
|
||||||
size_t list_pos = 0;
|
size_t list_pos = 0;
|
||||||
|
|
||||||
|
@ -551,15 +605,23 @@ coder_normal(file_pair *pair)
|
||||||
|
|
||||||
// If --block-list was used, start with the first size.
|
// If --block-list was used, start with the first size.
|
||||||
//
|
//
|
||||||
// FIXME: Currently this overrides --block-size but this isn't
|
// For threaded case, --block-size specifies how big Blocks
|
||||||
// good. For threaded case, we want --block-size to specify
|
// the encoder needs to be prepared to create at maximum
|
||||||
// how big Blocks the encoder needs to be prepared to create
|
// and --block-list will simultaneously cause new Blocks
|
||||||
// at maximum and --block-list will simultaneously cause new
|
// to be started at specified intervals. To keep things
|
||||||
// Blocks to be started at specified intervals. To keep things
|
// logical, the same is done in single-threaded mode. The
|
||||||
// logical, the same should be done in single-threaded mode.
|
// output is still not identical because in single-threaded
|
||||||
if (opt_block_list != NULL)
|
// mode the size info isn't written into Block Headers.
|
||||||
|
if (opt_block_list != NULL) {
|
||||||
|
if (block_remaining < opt_block_list[list_pos]) {
|
||||||
|
assert(hardware_threads_get() == 1);
|
||||||
|
next_block_remaining = opt_block_list[list_pos]
|
||||||
|
- block_remaining;
|
||||||
|
} else {
|
||||||
block_remaining = opt_block_list[list_pos];
|
block_remaining = opt_block_list[list_pos];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
strm.next_out = out_buf.u8;
|
strm.next_out = out_buf.u8;
|
||||||
strm.avail_out = IO_BUFFER_SIZE;
|
strm.avail_out = IO_BUFFER_SIZE;
|
||||||
|
@ -622,15 +684,13 @@ coder_normal(file_pair *pair)
|
||||||
} else {
|
} else {
|
||||||
// Start a new Block after LZMA_FULL_BARRIER.
|
// Start a new Block after LZMA_FULL_BARRIER.
|
||||||
if (opt_block_list == NULL) {
|
if (opt_block_list == NULL) {
|
||||||
|
assert(hardware_threads_get() == 1);
|
||||||
|
assert(opt_block_size > 0);
|
||||||
block_remaining = opt_block_size;
|
block_remaining = opt_block_size;
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Make it work together with
|
split_block(&block_remaining,
|
||||||
// --block-size.
|
&next_block_remaining,
|
||||||
if (opt_block_list[list_pos + 1] != 0)
|
&list_pos);
|
||||||
++list_pos;
|
|
||||||
|
|
||||||
block_remaining
|
|
||||||
= opt_block_list[list_pos];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue