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 block. Now this works in
single-threaded mode too.
---
 src/xz/coder.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 54 insertions(+), 4 deletions(-)

diff --git a/src/xz/coder.c b/src/xz/coder.c
index 61aa1f4..e035a4a 100644
--- a/src/xz/coder.c
+++ b/src/xz/coder.c
@@ -514,6 +514,43 @@ 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
+               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 is finished processing
+               if (opt_block_list[*list_pos + 1] != 0)
+                       *list_pos = *list_pos + 1;
+
+               *block_remaining = opt_block_list[*list_pos];
+               if (*block_remaining > opt_block_size) {
+                       *next_block_remaining = *block_remaining -
+                               opt_block_size;
+                       *block_remaining = opt_block_size;
+               }
+       }
+}
+               
+                       
 /// Compress or decompress using liblzma.
 static bool
 coder_normal(file_pair *pair)
@@ -537,6 +574,10 @@ coder_normal(file_pair *pair)
        // only a single block is created.
        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.
        size_t list_pos = 0;
 
@@ -557,8 +598,14 @@ coder_normal(file_pair *pair)
                // at maximum and --block-list will simultaneously cause new
                // Blocks to be started at specified intervals. To keep things
                // logical, the same should be done in single-threaded mode.
-               if (opt_block_list != NULL)
-                       block_remaining = opt_block_list[list_pos];
+               if (opt_block_list != NULL) {
+                       if (block_remaining < opt_block_list[list_pos]) {
+                               next_block_remaining = opt_block_list[list_pos] 
+                                       - block_remaining;
+                       } else {
+                               block_remaining = opt_block_list[list_pos];
+                       }
+               }
        }
 
        strm.next_out = out_buf.u8;
@@ -623,9 +670,12 @@ coder_normal(file_pair *pair)
                                // Start a new Block after LZMA_FULL_BARRIER.
                                if (opt_block_list == NULL) {
                                        block_remaining = opt_block_size;
+                               } else if (hardware_threads_get() == 1 && 
+                                          opt_block_size > 0) {
+                                       split_block(&block_remaining,
+                                                   &next_block_remaining,
+                                                   &list_pos);
                                } else {
-                                       // FIXME: Make it work together with
-                                       // --block-size.
                                        if (opt_block_list[list_pos + 1] != 0)
                                                ++list_pos;
 
-- 
1.8.3.2


Reply via email to