From: Eric Biggers Date: Thu, 23 May 2013 00:37:31 +0000 (-0500) Subject: Cache compression type in WIMStruct and wim_lookup_table_entry X-Git-Tag: v1.4.1~18 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=c9482ee98e12fa3f1073e4fc3c56f5eef3c40f32 Cache compression type in WIMStruct and wim_lookup_table_entry --- diff --git a/include/wimlib/lookup_table.h b/include/wimlib/lookup_table.h index aad400de..09775058 100644 --- a/include/wimlib/lookup_table.h +++ b/include/wimlib/lookup_table.h @@ -138,15 +138,21 @@ struct wim_lookup_table_entry { u16 resource_location : 5; /* 1 if this stream is a unique size (only set while writing streams). */ - u8 unique_size : 1; + u16 unique_size : 1; /* 1 if this stream has not had a SHA1 message digest calculated for it * yet */ - u8 unhashed : 1; + u16 unhashed : 1; - u8 deferred : 1; + u16 deferred : 1; - u8 no_progress : 1; + u16 no_progress : 1; + + /* If resource_location == RESOURCE_IN_WIM, this will be a cached value + * that specifies the compression type of this stream as one of + * WIMLIB_COMPRESSION_TYPE_*. Otherwise this will be 0, which is the + * same as WIMLIB_COMPRESSION_TYPE_NONE. */ + u16 compression_type : 2; /* (On-disk field) * Number of times this lookup table entry is referenced by dentries. @@ -268,8 +274,12 @@ wim_resource_compressed_size(const struct wim_lookup_table_entry *lte) return lte->resource_entry.size; } -extern int -wim_resource_compression_type(const struct wim_lookup_table_entry *lte); +static inline int +wim_resource_compression_type(const struct wim_lookup_table_entry *lte) +{ + BUILD_BUG_ON(WIMLIB_COMPRESSION_TYPE_NONE != 0); + return lte->compression_type; +} static inline bool lte_filename_valid(const struct wim_lookup_table_entry *lte) diff --git a/include/wimlib/wim.h b/include/wimlib/wim.h index a2d664ea..57adebde 100644 --- a/include/wimlib/wim.h +++ b/include/wimlib/wim.h @@ -55,6 +55,9 @@ struct WIMStruct { u8 refcnts_ok : 1; u8 wim_locked : 1; + + /* One of WIMLIB_COMPRESSION_TYPE_*, cached from the header flags. */ + u8 compression_type : 2; }; extern void diff --git a/src/join.c b/src/join.c index 35006541..2c459d30 100644 --- a/src/join.c +++ b/src/join.c @@ -158,8 +158,7 @@ wimlib_join(const tchar * const *swm_names, if (ret) goto out_free_wims; - ret = wimlib_create_new_wim(wimlib_get_compression_type(swms[0]), - &joined_wim); + ret = wimlib_create_new_wim(swms[0]->compression_type, &joined_wim); if (ret) goto out_free_wims; diff --git a/src/lookup_table.c b/src/lookup_table.c index c1bd00d3..ba832453 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -447,6 +447,11 @@ read_lookup_table(WIMStruct *w) cur_entry->refcnt = le32_to_cpu(disk_entry->refcnt); copy_hash(cur_entry->hash, disk_entry->hash); + if (cur_entry->resource_entry.flags & WIM_RESHDR_FLAG_COMPRESSED) + cur_entry->compression_type = w->compression_type; + else + BUILD_BUG_ON(WIMLIB_COMPRESSION_TYPE_NONE != 0); + if (cur_entry->part_number != w->hdr.part_number) { WARNING("A lookup table entry in part %hu of the WIM " "points to part %hu (ignoring it)", @@ -872,19 +877,6 @@ out: } #endif -/* - * XXX Probably should store the compression type directly in the lookup table - * entry - */ -int -wim_resource_compression_type(const struct wim_lookup_table_entry *lte) -{ - if (!(lte->resource_entry.flags & WIM_RESHDR_FLAG_COMPRESSED) - || lte->resource_location != RESOURCE_IN_WIM) - return WIMLIB_COMPRESSION_TYPE_NONE; - return wimlib_get_compression_type(lte->wim); -} - /* Resolve an inode's lookup table entries * * This replaces the SHA1 hash fields (which are used to lookup an entry in the diff --git a/src/metadata_resource.c b/src/metadata_resource.c index 5f392e52..d23b6b07 100644 --- a/src/metadata_resource.c +++ b/src/metadata_resource.c @@ -311,7 +311,7 @@ write_metadata_resource(WIMStruct *w) * is updated. */ ret = write_wim_resource_from_buffer(buf, metadata_original_size, w->out_fd, - wimlib_get_compression_type(w), + w->compression_type, <e->output_resource_entry, lte->hash); /* Note that although the SHA1 message digest of the metadata resource diff --git a/src/resource.c b/src/resource.c index f37b8958..84d4441b 100644 --- a/src/resource.c +++ b/src/resource.c @@ -460,7 +460,7 @@ read_partial_wim_resource(const struct wim_lookup_table_entry *lte, lte->resource_entry.size, lte->resource_entry.original_size, lte->resource_entry.offset, - wimlib_get_compression_type(wim), + wim->compression_type, size, offset, cb, diff --git a/src/swm.c b/src/swm.c index 58e594f8..19452db1 100644 --- a/src/swm.c +++ b/src/swm.c @@ -137,7 +137,7 @@ verify_swm_set(WIMStruct *w, WIMStruct **additional_swms, /* keep track of ctype and guid just to make sure they are the same for * all the WIMs. */ - ctype = wimlib_get_compression_type(w); + ctype = w->compression_type; guid = w->hdr.guid; { @@ -151,7 +151,7 @@ verify_swm_set(WIMStruct *w, WIMStruct **additional_swms, WIMStruct *swm = additional_swms[i]; - if (wimlib_get_compression_type(swm) != ctype) { + if (swm->compression_type != ctype) { ERROR("The split WIMs do not all have the same " "compression type"); return WIMLIB_ERR_SPLIT_INVALID; diff --git a/src/wim.c b/src/wim.c index a745c0a2..cfe100d6 100644 --- a/src/wim.c +++ b/src/wim.c @@ -115,22 +115,6 @@ for_image(WIMStruct *w, int image, int (*visitor)(WIMStruct *)) return 0; } -/* Returns the compression type given in the flags of a WIM header. */ -static int -wim_hdr_flags_compression_type(int wim_hdr_flags) -{ - if (wim_hdr_flags & WIM_HDR_FLAG_COMPRESSION) { - if (wim_hdr_flags & WIM_HDR_FLAG_COMPRESS_LZX) - return WIMLIB_COMPRESSION_TYPE_LZX; - else if (wim_hdr_flags & WIM_HDR_FLAG_COMPRESS_XPRESS) - return WIMLIB_COMPRESSION_TYPE_XPRESS; - else - return WIMLIB_COMPRESSION_TYPE_INVALID; - } else { - return WIMLIB_COMPRESSION_TYPE_NONE; - } -} - /* * Creates a WIMStruct for a new WIM file. */ @@ -160,6 +144,7 @@ wimlib_create_new_wim(int ctype, WIMStruct **w_ret) } w->lookup_table = table; w->refcnts_ok = 1; + w->compression_type = ctype; *w_ret = w; return 0; out_free: @@ -227,7 +212,7 @@ select_wim_image(WIMStruct *w, int image) WIMLIBAPI int wimlib_get_compression_type(const WIMStruct *w) { - return wim_hdr_flags_compression_type(w->hdr.flags); + return w->compression_type; } WIMLIBAPI const tchar * @@ -293,7 +278,7 @@ wimlib_print_wim_information(const WIMStruct *w) tputchar(T('\n')); tprintf(T("Image Count: %d\n"), hdr->image_count); tprintf(T("Compression: %"TS"\n"), - wimlib_get_compression_type_string(wimlib_get_compression_type(w))); + wimlib_get_compression_type_string(w->compression_type)); tprintf(T("Part Number: %d/%d\n"), hdr->part_number, hdr->total_parts); tprintf(T("Boot Index: %d\n"), hdr->boot_idx); tprintf(T("Size: %"PRIu64" bytes\n"), @@ -496,10 +481,25 @@ begin_read(WIMStruct *w, const tchar *in_wim_path, int open_flags, w->hdr.boot_idx = 0; } - if (wimlib_get_compression_type(w) == WIMLIB_COMPRESSION_TYPE_INVALID) { - ERROR("Invalid compression type (WIM header flags = 0x%x)", - w->hdr.flags); - return WIMLIB_ERR_INVALID_COMPRESSION_TYPE; + /* Check and cache the compression type */ + if (w->hdr.flags & WIM_HDR_FLAG_COMPRESSION) { + if (w->hdr.flags & WIM_HDR_FLAG_COMPRESS_LZX) { + if (w->hdr.flags & WIM_HDR_FLAG_COMPRESS_XPRESS) { + ERROR("Multiple compression flags are set in \"%"TS"\"", + in_wim_path); + return WIMLIB_ERR_INVALID_COMPRESSION_TYPE; + } + w->compression_type = WIMLIB_COMPRESSION_TYPE_LZX; + } else if (w->hdr.flags & WIM_HDR_FLAG_COMPRESS_XPRESS) { + w->compression_type = WIMLIB_COMPRESSION_TYPE_XPRESS; + } else { + ERROR("The compression flag is set on \"%"TS"\", but " + "neither the XPRESS nor LZX flag is set", + in_wim_path); + return WIMLIB_ERR_INVALID_COMPRESSION_TYPE; + } + } else { + BUILD_BUG_ON(WIMLIB_COMPRESSION_TYPE_NONE != 0); } if (open_flags & WIMLIB_OPEN_FLAG_CHECK_INTEGRITY) { diff --git a/src/write.c b/src/write.c index 3b2aa18e..54257e04 100644 --- a/src/write.c +++ b/src/write.c @@ -377,7 +377,7 @@ write_wim_resource(struct wim_lookup_table_entry *lte, if (!(flags & WIMLIB_RESOURCE_FLAG_RECOMPRESS) && lte->resource_location == RESOURCE_IN_WIM && out_ctype != WIMLIB_COMPRESSION_TYPE_NONE && - wimlib_get_compression_type(lte->wim) == out_ctype) + lte->wim->compression_type == out_ctype) { flags |= WIMLIB_RESOURCE_FLAG_RAW; write_ctx.doing_sha = false; @@ -1207,7 +1207,7 @@ main_thread_process_next_stream(struct wim_lookup_table_entry *lte, void *_ctx) ctx->out_ctype == WIMLIB_COMPRESSION_TYPE_NONE || (lte->resource_location == RESOURCE_IN_WIM && !(ctx->write_resource_flags & WIMLIB_RESOURCE_FLAG_RECOMPRESS) && - wimlib_get_compression_type(lte->wim) == ctx->out_ctype)) + lte->wim->compression_type == ctx->out_ctype)) { /* Stream is too small or isn't being compressed. Process it by * the main thread when we have a chance. We can't necessarily @@ -1713,7 +1713,7 @@ write_wim_streams(WIMStruct *wim, int image, int write_flags, return write_stream_list(&stream_list, wim->lookup_table, wim->out_fd, - wimlib_get_compression_type(wim), + wim->compression_type, write_flags, num_threads, progress_func); @@ -2133,7 +2133,7 @@ overwrite_wim_inplace(WIMStruct *w, int write_flags, ret = write_stream_list(&stream_list, w->lookup_table, w->out_fd, - wimlib_get_compression_type(w), + w->compression_type, write_flags, num_threads, progress_func);