Cache compression type in WIMStruct and wim_lookup_table_entry
authorEric Biggers <ebiggers3@gmail.com>
Thu, 23 May 2013 00:37:31 +0000 (19:37 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Thu, 23 May 2013 00:37:31 +0000 (19:37 -0500)
include/wimlib/lookup_table.h
include/wimlib/wim.h
src/join.c
src/lookup_table.c
src/metadata_resource.c
src/resource.c
src/swm.c
src/wim.c
src/write.c

index aad400d..0977505 100644 (file)
@@ -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)
index a2d664e..57adebd 100644 (file)
@@ -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
index 3500654..2c459d3 100644 (file)
@@ -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;
 
index c1bd00d..ba83245 100644 (file)
@@ -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
index 5f392e5..d23b6b0 100644 (file)
@@ -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,
                                             &lte->output_resource_entry,
                                             lte->hash);
        /* Note that although the SHA1 message digest of the metadata resource
index f37b895..84d4441 100644 (file)
@@ -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,
index 58e594f..19452db 100644 (file)
--- 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;
index a745c0a..cfe100d 100644 (file)
--- 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) {
index 3b2aa18..54257e0 100644 (file)
@@ -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);