From: Eric Biggers Date: Sun, 31 May 2015 04:16:33 +0000 (-0500) Subject: Iterate through inodes instead of dentries in xml_update_image_info() X-Git-Tag: v1.8.2~98 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=27c2e0401d76095286e5e2e0f81f4ccee3d45df3;ds=sidebyside Iterate through inodes instead of dentries in xml_update_image_info() Slightly simpler and faster. --- diff --git a/include/wimlib/dentry.h b/include/wimlib/dentry.h index 40a4c8e6..efaf1768 100644 --- a/include/wimlib/dentry.h +++ b/include/wimlib/dentry.h @@ -122,12 +122,6 @@ struct wim_dentry { struct list_head d_extraction_alias_node; }; -static inline bool -dentry_is_first_in_inode(const struct wim_dentry *dentry) -{ - return inode_first_dentry(dentry->d_inode) == dentry; -} - static inline bool will_extract_dentry(const struct wim_dentry *dentry) { diff --git a/src/xml.c b/src/xml.c index 0fb64723..f1180cca 100644 --- a/src/xml.c +++ b/src/xml.c @@ -89,8 +89,6 @@ struct image_info { bool wimboot; /* Note: must update clone_image_info() if adding new fields here */ - - struct blob_table *blob_table; /* temporary field */ }; /* A struct wim_info structure corresponds to the entire XML data for a WIM file. */ @@ -1163,28 +1161,20 @@ xml_set_memory_allocator(void *(*malloc_func)(size_t), xmlMemSetup(free_func, malloc_func, realloc_func, STRDUP); } -static int -calculate_dentry_statistics(struct wim_dentry *dentry, void *_info) +static u64 +inode_sum_stream_sizes(const struct wim_inode *inode, + const struct blob_table *blob_table) { - struct image_info *info = _info; - const struct wim_inode *inode = dentry->d_inode; - - if (inode_is_directory(inode)) - info->dir_count++; - else - info->file_count++; + u64 total_size = 0; for (unsigned i = 0; i < inode->i_num_streams; i++) { const struct blob_descriptor *blob; - blob = stream_blob(&inode->i_streams[i], info->blob_table); - if (!blob) - continue; - info->total_bytes += blob->size; - if (!dentry_is_first_in_inode(dentry)) - info->hard_link_bytes += blob->size; + blob = stream_blob(&inode->i_streams[i], blob_table); + if (blob) + total_size += blob->size; } - return 0; + return total_size; } /* @@ -1197,22 +1187,30 @@ calculate_dentry_statistics(struct wim_dentry *dentry, void *_info) void xml_update_image_info(WIMStruct *wim, int image) { - struct image_info *image_info; - - DEBUG("Updating the image info for image %d", image); - - image_info = &wim->wim_info->images[image - 1]; - - image_info->file_count = 0; - image_info->dir_count = 0; - image_info->total_bytes = 0; - image_info->hard_link_bytes = 0; - image_info->blob_table = wim->blob_table; + struct image_info *info; + struct wim_image_metadata *imd; + struct wim_inode *inode; + u64 size; + + info = &wim->wim_info->images[image - 1]; + imd = wim->image_metadata[image - 1]; + + info->file_count = 0; + info->dir_count = 0; + info->total_bytes = 0; + info->hard_link_bytes = 0; + + image_for_each_inode(inode, imd) { + if (inode_is_directory(inode)) + info->dir_count += inode->i_nlink; + else + info->file_count += inode->i_nlink; + size = inode_sum_stream_sizes(inode, wim->blob_table); + info->total_bytes += size * inode->i_nlink; + info->hard_link_bytes += size * (inode->i_nlink - 1); + } - for_dentry_in_tree(wim->image_metadata[image - 1]->root_dentry, - calculate_dentry_statistics, - image_info); - image_info->last_modification_time = now_as_wim_timestamp(); + info->last_modification_time = now_as_wim_timestamp(); } /* Adds an image to the XML information. */