From c00d84f0f2ea6547b0e5b73250a72cf0b0c5d7f4 Mon Sep 17 00:00:00 2001 From: Vreixo Formoso Date: Sat, 12 Jan 2008 02:43:07 +0100 Subject: [PATCH] Improve mangling algorithm, by using a hash table for name search. --- demo/ecma119_tree.c | 3 +++ src/ecma119_tree.c | 50 +++++++++++++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/demo/ecma119_tree.c b/demo/ecma119_tree.c index 7569243..deb206f 100644 --- a/demo/ecma119_tree.c +++ b/demo/ecma119_tree.c @@ -125,6 +125,9 @@ int main(int argc, char **argv) printf("\n\n"); ecma119_node_free(ecma119->root); + iso_rbtree_destroy(ecma119->files, iso_file_src_free); + free(ecma119->input_charset); + free(ecma119); iso_image_unref(image); return 0; } diff --git a/src/ecma119_tree.c b/src/ecma119_tree.c index ca9d37f..ace7b70 100644 --- a/src/ecma119_tree.c +++ b/src/ecma119_tree.c @@ -385,19 +385,6 @@ void sort_tree(Ecma119Node *root) } } -static -int contains_name(Ecma119Node *dir, const char *name) -{ - int i; - for (i = 0; i < dir->info.dir->nchildren; i++) { - Ecma119Node *child = dir->info.dir->children[i]; - if (!strcmp(child->iso_name, name)) { - return 1; - } - } - return 0; -} - /** * Ensures that the ISO name of each children of the given dir is unique, * changing some of them if needed. @@ -409,12 +396,28 @@ static int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len, int max_dir_len) { + int ret; int i, nchildren; Ecma119Node **children; + IsoHTable *table; int need_sort = 0; nchildren = dir->info.dir->nchildren; children = dir->info.dir->children; + + /* a hash table will temporary hold the names, for fast searching */ + ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash, + (compare_function_t)strcmp, &table); + if (ret < 0) { + return ret; + } + for (i = 0; i < nchildren; ++i) { + char *name = children[i]->iso_name; + ret = iso_htable_add(table, name, name); + if (ret < 0) { + goto mangle_cleanup; + } + } for (i = 0; i < nchildren; ++i) { char *name, *ext; @@ -483,7 +486,8 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len, * error, we don't support extensions < 3 * This can't happen with current limit of digits. */ - return ISO_ERROR; + ret = ISO_ERROR; + goto mangle_cleanup; } } /* ok, reduce name by digits */ @@ -523,7 +527,7 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len, ok = 0; break; } - if (!contains_name(dir, tmp)) { + if (!iso_htable_get(table, tmp, NULL)) { /* the name is unique, so it can be used */ break; } @@ -531,13 +535,18 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len, if (ok) { char *new = strdup(tmp); if (new == NULL) { - return ISO_MEM_ERROR; + ret = ISO_MEM_ERROR; + goto mangle_cleanup; } iso_msg_debug(img->image->messenger, "\"%s\" renamed to \"%s\"", children[k]->iso_name, new); + + iso_htable_remove(table, children[k]->iso_name, NULL); free(children[k]->iso_name); children[k]->iso_name = new; + iso_htable_add(table, new, new); + /* * if we change a name we need to sort again children * at the end @@ -555,7 +564,8 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len, } } if (digits == 8) { - return ISO_MANGLE_TOO_MUCH_FILES; + ret = ISO_MANGLE_TOO_MUCH_FILES; + goto mangle_cleanup; } i = j; } @@ -567,7 +577,11 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len, qsort(children, nchildren, sizeof(void*), cmp_node_name); } - return ISO_SUCCESS; + ret = ISO_SUCCESS; + +mangle_cleanup : ; + iso_htable_destroy(table, NULL); + return ret; } static