diff --git a/runzip.c b/runzip.c index 1d8c274..d3a8703 100644 --- a/runzip.c +++ b/runzip.c @@ -132,11 +132,12 @@ static i64 unzip_match(void *ss, i64 len, int fd_out, int fd_hist, uint32 *cksum /* decompress a section of an open file. Call fatal() on error return the number of bytes that have been retrieved */ -static i64 runzip_chunk(int fd_in, int fd_out, int fd_hist, i64 expected_size, i64 tally, char chunk_bytes) +static i64 runzip_chunk(int fd_in, int fd_out, int fd_hist, i64 expected_size, i64 tally) { uint32 good_cksum, cksum = 0; i64 len, ofs, total = 0; int l = -1, p = 0; + char chunk_bytes; struct stat st; uchar head; void *ss; @@ -165,6 +166,20 @@ static i64 runzip_chunk(int fd_in, int fd_out, int fd_hist, i64 expected_size, i if (fstat(fd_in, &st) != 0 || st.st_size-ofs == 0) return 0; + /* Determine the chunk_byte width size. Versions < 0.4 used 4 + * bytes for all offsets, version 0.4 used 8 bytes. Versions 0.5+ use + * a variable number of bytes depending on chunk size.*/ + if (control.major_version == 0 && control.minor_version < 4) + chunk_bytes = 4; + else if (control.major_version == 0 && control.minor_version == 4) + chunk_bytes = 8; + else { + /* Read in the stored chunk byte width from the file */ + if (read(fd_in, &chunk_bytes, 1) != 1) + fatal("Failed to read chunk_bytes size in runzip_chunk\n"); + } + print_maxverbose("\nExpected size: %lld\nChunk byte width: %d\n", expected_size, chunk_bytes); + ss = open_stream_in(fd_in, NUM_STREAMS); if (!ss) fatal("Failed to open_stream_in in runzip_chunk\n"); @@ -180,14 +195,11 @@ static i64 runzip_chunk(int fd_in, int fd_out, int fd_hist, i64 expected_size, i break; } p = 100 * ((double)(tally + total) / (double)expected_size); - if (SHOW_PROGRESS) { - if ( p != l ) { - prog_done = (double)(tally + total) / (double)divisor[divisor_index]; - print_output("%3d%% %9.2f / %9.2f %s\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", - p, prog_done, prog_tsize, suffix[divisor_index] ); - fflush(control.msgout); - l = p; - } + if ( p != l ) { + prog_done = (double)(tally + total) / (double)divisor[divisor_index]; + print_progress("%3d%% %9.2f / %9.2f %s\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", + p, prog_done, prog_tsize, suffix[divisor_index] ); + l = p; } } @@ -207,31 +219,12 @@ static i64 runzip_chunk(int fd_in, int fd_out, int fd_hist, i64 expected_size, i i64 runzip_fd(int fd_in, int fd_out, int fd_hist, i64 expected_size) { struct timeval start,end; - char chunk_bytes; i64 total = 0; gettimeofday(&start,NULL); - /* Determine the chunk_byte width size. Versions < 0.4 used 4 - * bytes for all offsets, version 0.4 used 8 bytes. Versions 0.5+ use - * a variable number of bytes depending on file size.*/ - if (control.major_version == 0 && control.minor_version < 4) - chunk_bytes = 4; - else if (control.major_version == 0 && control.minor_version == 4) - chunk_bytes = 8; - else { - int bits = 0; - - while (expected_size >> bits > 0) - bits++; - chunk_bytes = bits / 8; - if (bits % 8) - chunk_bytes++; - } - print_maxverbose("\nExpected size: %lld\nChunk byte width: %d\n", expected_size, chunk_bytes); - while (total < expected_size) - total += runzip_chunk(fd_in, fd_out, fd_hist, expected_size, total, chunk_bytes); + total += runzip_chunk(fd_in, fd_out, fd_hist, expected_size, total); gettimeofday(&end,NULL); print_progress("\nAverage DeCompression Speed: %6.3fMB/s\n", diff --git a/rzip.c b/rzip.c index 053d81a..da39f62 100644 --- a/rzip.c +++ b/rzip.c @@ -482,7 +482,6 @@ static void hash_search(struct rzip_state *st, uchar *buf, fstat(st->fd_in, &s1); fstat(st->fd_out, &s2); print_output("%2lld%%\r", pct); - fflush(control.msgout); lastpct = pct; } } @@ -495,7 +494,7 @@ static void hash_search(struct rzip_state *st, uchar *buf, } - if (control.flags & FLAG_VERBOSITY_MAX) + if (MAX_VERBOSE) show_distrib(st); if (st->last_match < buf + st->chunk_size) @@ -579,7 +578,7 @@ void rzip_fd(int fd_in, int fd_out) struct stat s, s2; struct rzip_state *st; i64 len, chunk_window, last_chunk = 0; - int pass = 0, passes, bits = 8; + int pass = 0, passes; unsigned int eta_hours, eta_minutes, eta_seconds, elapsed_hours, elapsed_minutes, elapsed_seconds; double finish_time, elapsed_time, chunkmbs; @@ -588,7 +587,7 @@ void rzip_fd(int fd_in, int fd_out) if (!st) fatal("Failed to allocate control state in rzip_fd\n"); - if (control.flags & FLAG_LZO_COMPRESS) { + if (LZO_COMPRESS) { if (lzo_init() != LZO_E_OK) fatal("lzo_init() failed\n"); } @@ -598,12 +597,6 @@ void rzip_fd(int fd_in, int fd_out) len = s.st_size; print_verbose("File size: %lld\n", len); - while (len >> bits > 0) - bits++; - st->chunk_bytes = bits / 8; - if (bits % 8) - st->chunk_bytes++; - print_maxverbose("Byte width: %d\n", st->chunk_bytes); chunk_window = control.window * CHUNK_MULTIPLE; @@ -622,6 +615,7 @@ void rzip_fd(int fd_in, int fd_out) while (len) { double pct_base, pct_multiple; i64 chunk, limit = 0; + int bits = 8; /* Flushing the dirty data will decrease our chances of * running out of memory when we allocate ram again on the @@ -637,6 +631,18 @@ void rzip_fd(int fd_in, int fd_out) st->chunk_size = chunk; print_maxverbose("Chunk size: %lld\n\n", chunk); + /* Determine the chunk byte width and write it to the file + * This allows archives of different chunk sizes to have + * optimal byte width entries. */ + while (chunk >> bits > 0) + bits++; + st->chunk_bytes = bits / 8; + if (bits % 8) + st->chunk_bytes++; + print_maxverbose("Byte width: %d\n", st->chunk_bytes); + if (write(fd_out, &st->chunk_bytes, 1) != 1) + fatal("Failed to write chunk_bytes size in rzip_fd\n"); + pct_base = (100.0 * (s.st_size - len)) / s.st_size; pct_multiple = ((double)chunk) / s.st_size; pass++; @@ -644,20 +650,18 @@ void rzip_fd(int fd_in, int fd_out) gettimeofday(¤t, NULL); /* this will count only when size > window */ if (last.tv_sec > 0) { - if (VERBOSE) { - elapsed_time = current.tv_sec - start.tv_sec; - finish_time = elapsed_time / (pct_base / 100.0); - elapsed_hours = (unsigned int)(elapsed_time) / 3600; - elapsed_minutes = (unsigned int)(elapsed_time - elapsed_hours * 3600) / 60; - elapsed_seconds = (unsigned int) elapsed_time - elapsed_hours * 60 - elapsed_minutes * 60; - eta_hours = (unsigned int)(finish_time - elapsed_time) / 3600; - eta_minutes = (unsigned int)((finish_time - elapsed_time) - eta_hours * 3600) / 60; - eta_seconds = (unsigned int)(finish_time - elapsed_time) - eta_hours * 60 - eta_minutes * 60; - chunkmbs=(last_chunk / 1024 / 1024) / (double)(current.tv_sec-last.tv_sec); - print_output("\nPass %d / %d -- Elapsed Time: %02d:%02d:%02d. ETA: %02d:%02d:%02d. Compress Speed: %3.3fMB/s.\n", - pass, passes, elapsed_hours, elapsed_minutes, elapsed_seconds, - eta_hours, eta_minutes, eta_seconds, chunkmbs); - } + elapsed_time = current.tv_sec - start.tv_sec; + finish_time = elapsed_time / (pct_base / 100.0); + elapsed_hours = (unsigned int)(elapsed_time) / 3600; + elapsed_minutes = (unsigned int)(elapsed_time - elapsed_hours * 3600) / 60; + elapsed_seconds = (unsigned int) elapsed_time - elapsed_hours * 60 - elapsed_minutes * 60; + eta_hours = (unsigned int)(finish_time - elapsed_time) / 3600; + eta_minutes = (unsigned int)((finish_time - elapsed_time) - eta_hours * 3600) / 60; + eta_seconds = (unsigned int)(finish_time - elapsed_time) - eta_hours * 60 - eta_minutes * 60; + chunkmbs=(last_chunk / 1024 / 1024) / (double)(current.tv_sec-last.tv_sec); + print_verbose("\nPass %d / %d -- Elapsed Time: %02d:%02d:%02d. ETA: %02d:%02d:%02d. Compress Speed: %3.3fMB/s.\n", + pass, passes, elapsed_hours, elapsed_minutes, elapsed_seconds, + eta_hours, eta_minutes, eta_seconds, chunkmbs); } last.tv_sec = current.tv_sec; last.tv_usec = current.tv_usec;