WIMBoot / system compression: try WOFADK in addition to WOF
[wimlib] / src / solid.c
index 94901d0f319922263d149b2a55874a7e4b8a6e8a..59971d46d0ac7a9ecaffe9032553593cbada655b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * solid.c
  *
- * Heuristic sorting of streams to optimize solid compression.
+ * Heuristic sorting of blobs to optimize solid compression.
  */
 
 /*
 #  include "config.h"
 #endif
 
+#include "wimlib/blob_table.h"
 #include "wimlib/dentry.h"
 #include "wimlib/encoding.h"
 #include "wimlib/endianness.h"
-#include "wimlib/lookup_table.h"
 #include "wimlib/metadata.h"
 #include "wimlib/paths.h"
 #include "wimlib/solid.h"
@@ -52,101 +52,98 @@ get_extension(const utf16lechar *name, size_t nbytes)
 /*
  * Sort order for solid compression:
  *
- * 1. Streams without sort names
+ * 1. Blobs without sort names
  *     - sorted by sequential order
- * 2. Streams with sort names:
- *    a. Streams whose sort name does not have an extension
+ * 2. Blobs with sort names:
+ *    a. Blobs whose sort name does not have an extension
  *       - sorted by sort name
- *    b. Streams whose sort name has an extension
+ *    b. Blobs whose sort name has an extension
  *        - sorted primarily by extension (case insensitive),
  *         secondarily by sort name (case insensitive)
  */
 static int
-cmp_streams_by_solid_sort_name(const void *p1, const void *p2)
+cmp_blobs_by_solid_sort_name(const void *p1, const void *p2)
 {
-       const struct wim_lookup_table_entry *lte1, *lte2;
+       const struct blob_descriptor *blob1, *blob2;
 
-       lte1 = *(const struct wim_lookup_table_entry **)p1;
-       lte2 = *(const struct wim_lookup_table_entry **)p2;
+       blob1 = *(const struct blob_descriptor **)p1;
+       blob2 = *(const struct blob_descriptor **)p2;
 
-       if (lte1->solid_sort_name) {
-               if (!lte2->solid_sort_name)
+       if (blob1->solid_sort_name) {
+               if (!blob2->solid_sort_name)
                        return 1;
-               const utf16lechar *extension1 = get_extension(lte1->solid_sort_name,
-                                                             lte1->solid_sort_name_nbytes);
-               const utf16lechar *extension2 = get_extension(lte2->solid_sort_name,
-                                                             lte2->solid_sort_name_nbytes);
+               const utf16lechar *extension1 = get_extension(blob1->solid_sort_name,
+                                                             blob1->solid_sort_name_nbytes);
+               const utf16lechar *extension2 = get_extension(blob2->solid_sort_name,
+                                                             blob2->solid_sort_name_nbytes);
                if (extension1) {
                        if (!extension2)
                                return 1;
-                       int res = cmp_utf16le_strings(extension1,
-                                                     utf16le_strlen(extension1) / sizeof(utf16lechar),
-                                                     extension2,
-                                                     utf16le_strlen(extension2) / sizeof(utf16lechar),
-                                                     true); /* case insensitive */
+                       int res = cmp_utf16le_strings_z(extension1,
+                                                       extension2,
+                                                       true); /* case insensitive */
                        if (res)
                                return res;
                } else {
                        if (extension2)
                                return -1;
                }
-               int res = cmp_utf16le_strings(lte1->solid_sort_name,
-                                             lte1->solid_sort_name_nbytes / sizeof(utf16lechar),
-                                             lte2->solid_sort_name,
-                                             lte2->solid_sort_name_nbytes / sizeof(utf16lechar),
+               int res = cmp_utf16le_strings(blob1->solid_sort_name,
+                                             blob1->solid_sort_name_nbytes / sizeof(utf16lechar),
+                                             blob2->solid_sort_name,
+                                             blob2->solid_sort_name_nbytes / sizeof(utf16lechar),
                                              true); /* case insensitive */
                if (res)
                        return res;
        } else {
-               if (lte2->solid_sort_name)
+               if (blob2->solid_sort_name)
                        return -1;
        }
-       return cmp_streams_by_sequential_order(p1, p2);
+       return cmp_blobs_by_sequential_order(p1, p2);
 }
 
 static void
-lte_set_solid_sort_name_from_inode(struct wim_lookup_table_entry *lte,
-                                  const struct wim_inode *inode)
+blob_set_solid_sort_name_from_inode(struct blob_descriptor *blob,
+                                   const struct wim_inode *inode)
 {
        const struct wim_dentry *dentry;
        const utf16lechar *best_name = NULL;
        size_t best_name_nbytes = SIZE_MAX;
 
-       if (lte->solid_sort_name) /* Sort name already set?  */
+       if (blob->solid_sort_name) /* Sort name already set?  */
                return;
 
        /* If this file has multiple names, choose the shortest one.  */
        inode_for_each_dentry(dentry, inode) {
-               if (dentry->file_name_nbytes < best_name_nbytes) {
-                       best_name = dentry->file_name;
-                       best_name_nbytes = dentry->file_name_nbytes;
+               if (dentry->d_name_nbytes < best_name_nbytes) {
+                       best_name = dentry->d_name;
+                       best_name_nbytes = dentry->d_name_nbytes;
                }
        }
-       lte->solid_sort_name = utf16le_dupz(best_name, best_name_nbytes);
-       lte->solid_sort_name_nbytes = best_name_nbytes;
+       blob->solid_sort_name = utf16le_dupz(best_name, best_name_nbytes);
+       blob->solid_sort_name_nbytes = best_name_nbytes;
 }
 
-struct temp_lookup_table {
+struct temp_blob_table {
        struct hlist_head *table;
        size_t capacity;
 };
 
 static int
-dentry_fill_in_solid_sort_names(struct wim_dentry *dentry, void *_lookup_table)
+dentry_fill_in_solid_sort_names(struct wim_dentry *dentry, void *_blob_table)
 {
-       const struct temp_lookup_table *lookup_table = _lookup_table;
+       const struct temp_blob_table *blob_table = _blob_table;
        const struct wim_inode *inode = dentry->d_inode;
        const u8 *hash;
        struct hlist_head *head;
-       struct hlist_node *cur;
-       struct wim_lookup_table_entry *lte;
-
-       hash = inode_unnamed_stream_hash(inode);
-       head = &lookup_table->table[load_size_t_unaligned(hash) %
-                                   lookup_table->capacity];
-       hlist_for_each_entry(lte, cur, head, hash_list_2) {
-               if (hashes_equal(hash, lte->hash)) {
-                       lte_set_solid_sort_name_from_inode(lte, inode);
+       struct blob_descriptor *blob;
+
+       hash = inode_get_hash_of_unnamed_data_stream(inode);
+       head = &blob_table->table[load_size_t_unaligned(hash) %
+                                 blob_table->capacity];
+       hlist_for_each_entry(blob, head, hash_list_2) {
+               if (hashes_equal(hash, blob->hash)) {
+                       blob_set_solid_sort_name_from_inode(blob, inode);
                        break;
                }
        }
@@ -162,55 +159,55 @@ image_fill_in_solid_sort_names(WIMStruct *wim)
 }
 
 int
-sort_stream_list_for_solid_compression(struct list_head *stream_list)
+sort_blob_list_for_solid_compression(struct list_head *blob_list)
 {
-       size_t num_streams = 0;
-       struct temp_lookup_table lookup_table;
+       size_t num_blobs = 0;
+       struct temp_blob_table blob_table;
        WIMStruct *wims[128];
        int num_wims = 0;
-       struct wim_lookup_table_entry *lte;
+       struct blob_descriptor *blob;
        int ret;
 
-       /* Count the number of streams to be written.  */
-       list_for_each_entry(lte, stream_list, write_streams_list)
-               num_streams++;
+       /* Count the number of blobs to be written.  */
+       list_for_each_entry(blob, blob_list, write_blobs_list)
+               num_blobs++;
 
-       /* Allocate a temporary hash table for mapping stream hash => stream  */
-       lookup_table.capacity = num_streams;
-       lookup_table.table = CALLOC(lookup_table.capacity,
-                                   sizeof(lookup_table.table[0]));
-       if (!lookup_table.table)
+       /* Allocate a temporary hash table for mapping blob hash => blob  */
+       blob_table.capacity = num_blobs;
+       blob_table.table = CALLOC(blob_table.capacity,
+                                 sizeof(blob_table.table[0]));
+       if (!blob_table.table)
                return WIMLIB_ERR_NOMEM;
 
        /*
-        * For each stream to be written:
+        * For each blob to be written:
         * - Reset the sort name
         * - If it's in non-solid WIM resource, then save the WIMStruct.
         * - If it's in a file on disk, then set its sort name from that.
         */
-       list_for_each_entry(lte, stream_list, write_streams_list) {
-               lte->solid_sort_name = NULL;
-               lte->solid_sort_name_nbytes = 0;
-               switch (lte->resource_location) {
-               case RESOURCE_IN_WIM:
-                       if (lte->size != lte->rspec->uncompressed_size)
+       list_for_each_entry(blob, blob_list, write_blobs_list) {
+               blob->solid_sort_name = NULL;
+               blob->solid_sort_name_nbytes = 0;
+               switch (blob->blob_location) {
+               case BLOB_IN_WIM:
+                       if (blob->size != blob->rdesc->uncompressed_size)
                                continue;
                        for (int i = 0; i < num_wims; i++)
-                               if (lte->rspec->wim == wims[i])
+                               if (blob->rdesc->wim == wims[i])
                                        goto found_wim;
                        if (num_wims >= ARRAY_LEN(wims))
                                continue;
-                       wims[num_wims++] = lte->rspec->wim;
+                       wims[num_wims++] = blob->rdesc->wim;
                found_wim:
-                       hlist_add_head(&lte->hash_list_2,
-                                      &lookup_table.table[load_size_t_unaligned(lte->hash) %
-                                                          lookup_table.capacity]);
+                       hlist_add_head(&blob->hash_list_2,
+                                      &blob_table.table[load_size_t_unaligned(blob->hash) %
+                                                        blob_table.capacity]);
                        break;
-               case RESOURCE_IN_FILE_ON_DISK:
+               case BLOB_IN_FILE_ON_DISK:
        #ifdef __WIN32__
-               case RESOURCE_IN_WINNT_FILE_ON_DISK:
+               case BLOB_IN_WINNT_FILE_ON_DISK:
        #endif
-                       lte_set_solid_sort_name_from_inode(lte, lte->file_inode);
+                       blob_set_solid_sort_name_from_inode(blob, blob->file_inode);
                        break;
                default:
                        break;
@@ -218,27 +215,26 @@ sort_stream_list_for_solid_compression(struct list_head *stream_list)
        }
 
        /* For each WIMStruct that was found, search for dentry references to
-        * each stream and fill in the sort name this way.  This is useful e.g.
+        * each blob and fill in the sort name this way.  This is useful e.g.
         * when exporting a solid WIM file from a non-solid WIM file.  */
        for (int i = 0; i < num_wims; i++) {
                if (!wim_has_metadata(wims[i]))
                        continue;
-               wims[i]->private = &lookup_table;
+               wims[i]->private = &blob_table;
                ret = for_image(wims[i], WIMLIB_ALL_IMAGES,
                                image_fill_in_solid_sort_names);
                if (ret)
-                       goto out_free_lookup_table;
+                       goto out;
                deselect_current_wim_image(wims[i]);
        }
 
-       ret = sort_stream_list(stream_list,
-                              offsetof(struct wim_lookup_table_entry,
-                                       write_streams_list),
-                              cmp_streams_by_solid_sort_name);
+       ret = sort_blob_list(blob_list,
+                            offsetof(struct blob_descriptor, write_blobs_list),
+                            cmp_blobs_by_solid_sort_name);
 
-       list_for_each_entry(lte, stream_list, write_streams_list)
-               FREE(lte->solid_sort_name);
-out_free_lookup_table:
-       FREE(lookup_table.table);
+out:
+       list_for_each_entry(blob, blob_list, write_blobs_list)
+               FREE(blob->solid_sort_name);
+       FREE(blob_table.table);
        return ret;
 }