Change the byte width to be variable depending on chunk size, and write it as a single char describing the next byte width for decompression.

More minor tidying.
This commit is contained in:
Con Kolivas 2010-11-01 13:28:49 +11:00
parent cb27097cb4
commit 1ed2ce423f
2 changed files with 50 additions and 53 deletions

View file

@ -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",

52
rzip.c
View file

@ -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(&current, 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;