Only decode wanted blocks

pull/2/head
Dave Vasilevsky 14 years ago
parent 5b9896d074
commit 8b5dcf2e47

@ -7,12 +7,20 @@
* - verify file-index matches archive contents * - verify file-index matches archive contents
*/ */
#define DEBUG 1
#if DEBUG
#define debug(str, ...) fprintf(stderr, str "\n", ##__VA_ARGS__)
#else
#define debug(...)
#endif
typedef struct wanted_t wanted_t; typedef struct wanted_t wanted_t;
struct wanted_t { struct wanted_t {
wanted_t *next; wanted_t *next;
char *name; char *name;
size_t offset; size_t start, end, size;
size_t size;
}; };
static wanted_t *gWantedFiles = NULL; static wanted_t *gWantedFiles = NULL;
@ -60,14 +68,10 @@ int main(int argc, char **argv) {
} }
} }
// Set up file index
gFileIndexOffset = read_file_index(); gFileIndexOffset = read_file_index();
wanted_files(argc - optind, argv + optind); wanted_files(argc - optind, argv + optind);
for (wanted_t *w = gWantedFiles; w; w = w->next)
printf("want: %s\n", w->name);
exit(0);
set_block_sizes(); set_block_sizes();
pipeline_create(block_create, block_free, read_thread, decode_thread); pipeline_create(block_create, block_free, read_thread, decode_thread);
pipeline_item_t *pi; pipeline_item_t *pi;
while ((pi = pipeline_merged())) { while ((pi = pipeline_merged())) {
@ -115,6 +119,7 @@ static void set_block_sizes() {
static void read_thread(void) { static void read_thread(void) {
off_t offset = ftello(gInFile); off_t offset = ftello(gInFile);
wanted_t *w = gWantedFiles;
lzma_index_iter iter; lzma_index_iter iter;
lzma_index_iter_init(&iter, gIndex); lzma_index_iter_init(&iter, gIndex);
@ -125,6 +130,18 @@ static void read_thread(void) {
if (gFileIndexOffset && boffset == gFileIndexOffset) if (gFileIndexOffset && boffset == gFileIndexOffset)
continue; continue;
// Do we need this block?
if (gWantedFiles) {
size_t uend = iter.block.uncompressed_file_offset +
iter.block.uncompressed_size;
if (!w || w->start >= uend) {
debug("read: skip %llu", iter.block.number_in_file);
continue;
}
for ( ; w && w->end < uend; w = w->next) ;
}
debug("read: want %llu", iter.block.number_in_file);
// Get a block to work with // Get a block to work with
pipeline_item_t *pi; pipeline_item_t *pi;
queue_pop(gPipelineStartQ, (void**)&pi); queue_pop(gPipelineStartQ, (void**)&pi);
@ -147,7 +164,7 @@ static void read_thread(void) {
} }
static void wanted_free(wanted_t *w) { static void wanted_free(wanted_t *w) {
for (wanted_t *w = gWantedFiles; w; w = w->next) { for (wanted_t *w = gWantedFiles; w; ) {
wanted_t *tmp = w->next; wanted_t *tmp = w->next;
free(w); free(w);
w = tmp; w = tmp;
@ -184,8 +201,9 @@ static void wanted_files(size_t count, char **specs) {
} }
if (match && (!*nc || *nc == '/')) { // prefix must be at dir bound if (match && (!*nc || *nc == '/')) { // prefix must be at dir bound
wanted_t *w = malloc(sizeof(wanted_t)); wanted_t *w = malloc(sizeof(wanted_t));
*w = (wanted_t){ .name = f->name, .offset = f->offset, *w = (wanted_t){ .name = f->name, .start = f->offset,
.size = f->next->offset - f->offset, .next = NULL }; .end = f->next->offset, .next = NULL };
w->size = w->end - w->start;
if (last) { if (last) {
last->next = w; last->next = w;
} else { } else {

Loading…
Cancel
Save