X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fsolid.c;h=59971d46d0ac7a9ecaffe9032553593cbada655b;hp=94901d0f319922263d149b2a55874a7e4b8a6e8a;hb=873a86a1a5097f2a161494341d8d962453a30465;hpb=d8e380e8314cdb592149a651a19690d102a1865b diff --git a/src/solid.c b/src/solid.c index 94901d0f..59971d46 100644 --- a/src/solid.c +++ b/src/solid.c @@ -1,7 +1,7 @@ /* * solid.c * - * Heuristic sorting of streams to optimize solid compression. + * Heuristic sorting of blobs to optimize solid compression. */ /* @@ -25,10 +25,10 @@ # 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(<e->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; }