diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-01-26 15:00:03 +0100 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-01-26 15:09:06 +0100 |
commit | daa1409632c380f88150be29889714044a843dcc (patch) | |
tree | 20cc4079c6812c97eaa960f81f7e1cfe863013bf /lib/sqfs/data_writer/fragment.c | |
parent | 4f92cc1f0ab3202d0949d316e85f486c4312358b (diff) |
Cleanup: Move fragment deduplication code over to fragment table
This removes further clutter from the data writer. Any future efforts
on making fragment by hash lookup faster can focus on that area only
and don't clutter the block processor.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/sqfs/data_writer/fragment.c')
-rw-r--r-- | lib/sqfs/data_writer/fragment.c | 84 |
1 files changed, 24 insertions, 60 deletions
diff --git a/lib/sqfs/data_writer/fragment.c b/lib/sqfs/data_writer/fragment.c index 70679c9..9862c89 100644 --- a/lib/sqfs/data_writer/fragment.c +++ b/lib/sqfs/data_writer/fragment.c @@ -7,68 +7,18 @@ #define SQFS_BUILDING_DLL #include "internal.h" -static int grow_deduplication_list(sqfs_data_writer_t *proc) -{ - size_t new_sz; - void *new; - - if (proc->frag_list_num == proc->frag_list_max) { - new_sz = proc->frag_list_max * 2; - new = realloc(proc->frag_list, - sizeof(proc->frag_list[0]) * new_sz); - - if (new == NULL) - return SQFS_ERROR_ALLOC; - - proc->frag_list = new; - proc->frag_list_max = new_sz; - } - - return 0; -} - -static int store_fragment(sqfs_data_writer_t *proc, sqfs_block_t *frag, - sqfs_u64 hash) -{ - int err = grow_deduplication_list(proc); - - if (err) - return err; - - proc->frag_list[proc->frag_list_num].index = proc->frag_block->index; - proc->frag_list[proc->frag_list_num].offset = proc->frag_block->size; - proc->frag_list[proc->frag_list_num].hash = hash; - proc->frag_list_num += 1; - - sqfs_inode_set_frag_location(frag->inode, proc->frag_block->index, - proc->frag_block->size); - - if (proc->hooks != NULL && proc->hooks->pre_fragment_store != NULL) { - proc->hooks->pre_fragment_store(proc->user_ptr, frag); - } - - memcpy(proc->frag_block->data + proc->frag_block->size, - frag->data, frag->size); - - proc->frag_block->flags |= (frag->flags & SQFS_BLK_DONT_COMPRESS); - proc->frag_block->size += frag->size; - return 0; -} - int process_completed_fragment(sqfs_data_writer_t *proc, sqfs_block_t *frag, sqfs_block_t **blk_out) { - sqfs_u64 hash; - sqfs_u32 index; - size_t i, size; + sqfs_u32 index, offset; + size_t size; int err; - hash = MK_BLK_HASH(frag->checksum, frag->size); - - for (i = 0; i < proc->frag_list_num; ++i) { - if (proc->frag_list[i].hash == hash) - goto out_duplicate; - } + err = sqfs_frag_table_find_tail_end(proc->frag_tbl, + frag->checksum, frag->size, + &index, &offset); + if (err == 0) + goto out_duplicate; if (proc->frag_block != NULL) { size = proc->frag_block->size + frag->size; @@ -96,18 +46,32 @@ int process_completed_fragment(sqfs_data_writer_t *proc, sqfs_block_t *frag, proc->frag_block->flags = SQFS_BLK_FRAGMENT_BLOCK; } - err = store_fragment(proc, frag, hash); + err = sqfs_frag_table_add_tail_end(proc->frag_tbl, + proc->frag_block->index, + proc->frag_block->size, + frag->size, frag->checksum); if (err) goto fail; + sqfs_inode_set_frag_location(frag->inode, proc->frag_block->index, + proc->frag_block->size); + + if (proc->hooks != NULL && proc->hooks->pre_fragment_store != NULL) { + proc->hooks->pre_fragment_store(proc->user_ptr, frag); + } + + memcpy(proc->frag_block->data + proc->frag_block->size, + frag->data, frag->size); + + proc->frag_block->flags |= (frag->flags & SQFS_BLK_DONT_COMPRESS); + proc->frag_block->size += frag->size; return 0; fail: free(*blk_out); *blk_out = NULL; return err; out_duplicate: - sqfs_inode_set_frag_location(frag->inode, proc->frag_list[i].index, - proc->frag_list[i].offset); + sqfs_inode_set_frag_location(frag->inode, index, offset); if (proc->hooks != NULL && proc->hooks->notify_fragment_discard != NULL) { |