}
}
+static void
+lookup_table_insert_raw(struct wim_lookup_table *table,
+ struct wim_lookup_table_entry *lte)
+{
+ size_t i = lte->hash_short % table->capacity;
+
+ hlist_add_head(<e->hash_list, &table->array[i]);
+}
+
+static void
+enlarge_lookup_table(struct wim_lookup_table *table)
+{
+ size_t old_capacity, new_capacity;
+ struct hlist_head *old_array, *new_array;
+ struct wim_lookup_table_entry *lte;
+ struct hlist_node *cur, *tmp;
+ size_t i;
+
+ old_capacity = table->capacity;
+ new_capacity = old_capacity * 2;
+ new_array = CALLOC(new_capacity, sizeof(struct hlist_head));
+ if (new_array == NULL)
+ return;
+ old_array = table->array;
+ table->array = new_array;
+ table->capacity = new_capacity;
+
+ for (i = 0; i < old_capacity; i++) {
+ hlist_for_each_entry_safe(lte, cur, tmp, &old_array[i], hash_list) {
+ hlist_del(<e->hash_list);
+ lookup_table_insert_raw(table, lte);
+ }
+ }
+ FREE(old_array);
+}
+
+
/*
* Inserts an entry into the lookup table.
*
lookup_table_insert(struct wim_lookup_table *table,
struct wim_lookup_table_entry *lte)
{
- size_t i = lte->hash_short % table->capacity;
- hlist_add_head(<e->hash_list, &table->array[i]);
-
- /* XXX Make the table grow when too many entries have been inserted. */
- table->num_entries++;
+ lookup_table_insert_raw(table, lte);
+ if (++table->num_entries > table->capacity)
+ enlarge_lookup_table(table);
}
static void
hlist_for_each_entry_safe(lte, pos, tmp, &table->array[i],
hash_list)
{
- wimlib_assert2(!(lte->resource_entry.flags & WIM_RESHDR_FLAG_METADATA));
ret = visitor(lte, arg);
if (ret)
return ret;
if (v)
return v;
- return cmp_u64(lte1->rspec->offset_in_wim + lte1->offset_in_res,
- lte2->rspec->offset_in_wim + lte2->offset_in_res);
+ if (lte1->rspec->offset_in_wim != lte2->rspec->offset_in_wim)
+ return cmp_u64(lte1->rspec->offset_in_wim,
+ lte2->rspec->offset_in_wim);
+
+ return cmp_u64(lte1->offset_in_res, lte2->offset_in_res);
case RESOURCE_IN_FILE_ON_DISK:
#ifdef WITH_FUSE
goto invalid;
/* Verify that each stream in the resource has a valid offset and size,
- * and that no streams overlap. */
+ * and that no streams overlap, and that the streams were added in order
+ * of increasing offset. */
cur_offset = 0;
list_for_each_entry(lte, &rspec->stream_list, rspec_node) {
if (lte->offset_in_res + lte->size < lte->size ||
reshdr.size_in_wim, reshdr.uncompressed_size,
reshdr.offset_in_wim, reshdr.flags);
+ if (wim->hdr.wim_version == WIM_VERSION_DEFAULT)
+ reshdr.flags &= ~WIM_RESHDR_FLAG_PACKED_STREAMS;
+
cur_entry = new_lookup_table_entry();
if (cur_entry == NULL) {
ERROR("Not enough memory to read lookup table!");
* resource. */
struct wim_lookup_table_entry *prev_entry = NULL;
- if (back_to_back_pack) {
+ if (back_to_back_pack &&
+ !list_empty(&cur_rspec->stream_list))
+ {
prev_entry = list_entry(cur_rspec->stream_list.prev,
struct wim_lookup_table_entry,
rspec_node);
if (reshdr.flags & WIM_RESHDR_FLAG_PACKED_STREAMS) {
cur_rspec->size_in_wim = 0;
cur_rspec->uncompressed_size = 0;
- cur_rspec->flags = WIM_RESHDR_FLAG_PACKED_STREAMS;
+ cur_rspec->offset_in_wim = 0;
}
if (prev_entry) {
goto out_free_buf;
out_free_cur_entry:
- FREE(cur_entry);
+ free_lookup_table_entry(cur_entry);
out_free_lookup_table:
free_lookup_table(table);
out_free_buf:
struct filedes *out_fd,
u16 part_number,
struct wim_reshdr *out_reshdr,
- int write_resource_flags,
- struct wimlib_lzx_context **comp_ctx)
+ int write_resource_flags)
{
size_t table_size;
struct wim_lookup_table_entry *lte;
0,
out_reshdr,
NULL,
- write_resource_flags,
- comp_ctx);
+ write_resource_flags);
FREE(table_buf);
DEBUG("ret=%d", ret);
return ret;
wentry->offset = lte->rspec->offset_in_wim;
}
wentry->raw_resource_offset_in_wim = lte->rspec->offset_in_wim;
- wentry->raw_resource_uncompressed_size = lte->rspec->uncompressed_size;
+ /*wentry->raw_resource_uncompressed_size = lte->rspec->uncompressed_size;*/
wentry->raw_resource_compressed_size = lte->rspec->size_in_wim;
}
copy_hash(wentry->sha1_hash, lte->hash);
wentry->is_metadata = (lte->flags & WIM_RESHDR_FLAG_METADATA) != 0;
wentry->is_free = (lte->flags & WIM_RESHDR_FLAG_FREE) != 0;
wentry->is_spanned = (lte->flags & WIM_RESHDR_FLAG_SPANNED) != 0;
- wentry->is_packed_streams = (lte->flags & WIM_RESHDR_FLAG_PACKED_STREAMS) != 0;
+ wentry->packed = (lte->flags & WIM_RESHDR_FLAG_PACKED_STREAMS) != 0;
}
struct iterate_lte_context {
}
}
- dentry = get_dentry(wim, path);
+ dentry = get_dentry(wim, path, WIMLIB_CASE_SENSITIVE);
if (p)
*p = T(':');
if (!dentry)