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/frag_table.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/frag_table.c')
-rw-r--r-- | lib/sqfs/frag_table.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/sqfs/frag_table.c b/lib/sqfs/frag_table.c index 3373a3c..200f3d5 100644 --- a/lib/sqfs/frag_table.c +++ b/lib/sqfs/frag_table.c @@ -17,10 +17,24 @@ #include <stdlib.h> #include <string.h> + +typedef struct { + sqfs_u32 index; + sqfs_u32 offset; + sqfs_u32 size; + sqfs_u32 hash; +} chunk_info_t; + + struct sqfs_frag_table_t { size_t capacity; size_t used; sqfs_fragment_t *table; + + /* TODO: more efficient data structure */ + size_t chunk_num; + size_t chunk_max; + chunk_info_t *chunk_list; }; sqfs_frag_table_t *sqfs_frag_table_create(sqfs_u32 flags) @@ -39,6 +53,7 @@ sqfs_frag_table_t *sqfs_frag_table_create(sqfs_u32 flags) void sqfs_frag_table_destroy(sqfs_frag_table_t *tbl) { + free(tbl->chunk_list); free(tbl->table); free(tbl); } @@ -193,3 +208,50 @@ size_t sqfs_frag_table_get_size(sqfs_frag_table_t *tbl) { return tbl->used; } + +int sqfs_frag_table_add_tail_end(sqfs_frag_table_t *tbl, + sqfs_u32 index, sqfs_u32 offset, + sqfs_u32 size, sqfs_u32 hash) +{ + size_t new_sz; + void *new; + + if (tbl->chunk_num == tbl->chunk_max) { + new_sz = tbl->chunk_max ? tbl->chunk_max * 2 : 128; + new = realloc(tbl->chunk_list, + sizeof(tbl->chunk_list[0]) * new_sz); + + if (new == NULL) + return SQFS_ERROR_ALLOC; + + tbl->chunk_list = new; + tbl->chunk_max = new_sz; + } + + tbl->chunk_list[tbl->chunk_num].index = index; + tbl->chunk_list[tbl->chunk_num].offset = offset; + tbl->chunk_list[tbl->chunk_num].size = size; + tbl->chunk_list[tbl->chunk_num].hash = hash; + tbl->chunk_num += 1; + return 0; +} + +int sqfs_frag_table_find_tail_end(sqfs_frag_table_t *tbl, + sqfs_u32 hash, sqfs_u32 size, + sqfs_u32 *index, sqfs_u32 *offset) +{ + size_t i; + + for (i = 0; i < tbl->chunk_num; ++i) { + if (tbl->chunk_list[i].hash == hash && + tbl->chunk_list[i].size == size) { + if (index != NULL) + *index = tbl->chunk_list[i].index; + if (offset != NULL) + *offset = tbl->chunk_list[i].offset; + return 0; + } + } + + return SQFS_ERROR_NO_ENTRY; +} |