From 44926cd53c3e99f66b63338df6c81ab98fe6cc71 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Sat, 4 Apr 2009 05:24:58 +0200 Subject: [PATCH] Performance improvements while installing deps of a binpkg. --HG-- extra : convert_revision : 2ad3b29cfd22489f76739287176f40dd9535dfee --- bin/xbps-repo/index.c | 3 +- include/install.h | 2 +- include/plist.h | 2 +- lib/depends.c | 123 +++++++------------------------ lib/install.c | 167 +++++++++++++++++++++--------------------- lib/plist.c | 9 ++- lib/sortdeps.c | 2 +- lib/unpack.c | 3 +- 8 files changed, 123 insertions(+), 188 deletions(-) diff --git a/bin/xbps-repo/index.c b/bin/xbps-repo/index.c index fc277aca7d9..91966e3bbc4 100644 --- a/bin/xbps-repo/index.c +++ b/bin/xbps-repo/index.c @@ -176,7 +176,8 @@ repoidx_addpkg(const char *file, const char *filename, const char *pkgdir) * registered actually, remove old package from * the index. */ - if (!xbps_remove_pkg_from_dict(idxdict, pkgname)) { + if (!xbps_remove_pkg_from_dict(idxdict, + "packages", pkgname)) { prop_object_release(newpkgd); rv = EINVAL; break; diff --git a/include/install.h b/include/install.h index dde55a7c7b1..4c14dddb641 100644 --- a/include/install.h +++ b/include/install.h @@ -35,7 +35,7 @@ int xbps_register_pkg(prop_dictionary_t, bool, bool); int xbps_unpack_binary_pkg(prop_dictionary_t, prop_dictionary_t); int xbps_requiredby_pkg_add(prop_array_t, prop_dictionary_t, bool); int xbps_requiredby_pkg_remove(const char *); -int xbps_find_deps_in_pkg(prop_dictionary_t); +int xbps_find_deps_in_pkg(prop_dictionary_t, prop_object_iterator_t); prop_dictionary_t xbps_get_pkg_deps_dictionary(void); diff --git a/include/plist.h b/include/plist.h index 3582cb0992d..0f23c73ac15 100644 --- a/include/plist.h +++ b/include/plist.h @@ -105,6 +105,6 @@ bool xbps_remove_pkg_dict_from_file(const char *, const char *); bool -xbps_remove_pkg_from_dict(prop_dictionary_t, const char *); +xbps_remove_pkg_from_dict(prop_dictionary_t, const char *, const char *); #endif /* !_XBPS_PLIST_H_ */ diff --git a/lib/depends.c b/lib/depends.c index 4facfc590ae..c7a541204dd 100644 --- a/lib/depends.c +++ b/lib/depends.c @@ -33,7 +33,6 @@ #include static int add_missing_reqdep(const char *, const char *); -static int remove_missing_reqdep(const char *); static int find_pkg_deps_from_repo(prop_dictionary_t, prop_dictionary_t, prop_array_t); static int find_pkg_missing_deps_from_repo(prop_dictionary_t, @@ -208,88 +207,22 @@ add_missing_reqdep(const char *pkgname, const char *version) return 0; } -static int -remove_missing_reqdep(const char *pkgname) -{ - prop_array_t array; - prop_object_t obj; - prop_object_iterator_t iter; - size_t idx = 0; - const char *curname; - bool found = false; - - array = prop_dictionary_get(chaindeps, "missing_deps"); - assert(pkgname != NULL); - assert(version != NULL); - assert(array != NULL); - iter = prop_array_iterator(array); - if (iter == NULL) - return ENOMEM; - /* - * Finds the index of a package in the missing deps array. - */ - while ((obj = prop_object_iterator_next(iter)) != NULL) { - prop_dictionary_get_cstring_nocopy(obj, "pkgname", &curname); - if (strcmp(pkgname, curname) == 0) { - found = true; - break; - } - idx++; - } - prop_object_iterator_release(iter); - if (found) { - prop_array_remove(array, idx); - return 0; - } - - return ENOENT; -} - int -xbps_find_deps_in_pkg(prop_dictionary_t pkg) +xbps_find_deps_in_pkg(prop_dictionary_t pkg, prop_object_iterator_t iter) { - prop_array_t array, pkg_rdeps, missing_rdeps; - prop_dictionary_t repolistd, repod; + prop_array_t pkg_rdeps, missing_rdeps; + prop_dictionary_t repod; prop_object_t obj; - prop_object_iterator_t iter; char *plist; int rv = 0; assert(pkg != NULL); + assert(iter != NULL); pkg_rdeps = prop_dictionary_get(pkg, "run_depends"); if (pkg_rdeps == NULL) return 0; - /* - * Get the dictionary with the list of registered repositories. - */ - plist = xbps_append_full_path(true, NULL, XBPS_REPOLIST); - if (plist == NULL) - return EINVAL; - /* - * Get the dictionary with the list of registered repositories. - */ - repolistd = prop_dictionary_internalize_from_file(plist); - if (repolistd == NULL) { - free(plist); - return EINVAL; - } - free(plist); - plist = NULL; - - array = prop_dictionary_get(repolistd, "repository-list"); - if (array == NULL) { - prop_object_release(repolistd); - return EINVAL; - } - - iter = prop_array_iterator(array); - if (iter == NULL) { - prop_object_release(repolistd); - return ENOMEM; - } - /* * Iterate over the repository pool and find out if we have * all available binary packages. @@ -297,15 +230,13 @@ xbps_find_deps_in_pkg(prop_dictionary_t pkg) while ((obj = prop_object_iterator_next(iter)) != NULL) { plist = xbps_get_pkg_index_plist(prop_string_cstring_nocopy(obj)); - if (plist == NULL) { - rv = EINVAL; - goto out; - } + if (plist == NULL) + return EINVAL; + repod = prop_dictionary_internalize_from_file(plist); if (repod == NULL) { free(plist); - rv = errno; - goto out; + return errno; } free(plist); @@ -329,7 +260,7 @@ xbps_find_deps_in_pkg(prop_dictionary_t pkg) missing_rdeps = prop_dictionary_get(chaindeps, "missing_deps"); if (prop_array_count(missing_rdeps) == 0) - goto out; + return 0; /* * If there are missing deps, iterate one more time @@ -339,32 +270,26 @@ xbps_find_deps_in_pkg(prop_dictionary_t pkg) while ((obj = prop_object_iterator_next(iter)) != NULL) { plist = xbps_get_pkg_index_plist(prop_string_cstring_nocopy(obj)); - if (plist == NULL) { - rv = EINVAL; - goto out; - } + if (plist == NULL) + return EINVAL; + repod = prop_dictionary_internalize_from_file(plist); if (repod == NULL) { free(plist); - rv = errno; - goto out; + return errno; } free(plist); rv = find_pkg_missing_deps_from_repo(repod, pkg); if (rv != 0 && rv != ENOENT) { prop_object_release(repod); - break; + return rv; } prop_object_release(repod); } -out: - prop_object_iterator_release(iter); - prop_object_release(repolistd); - - return rv; + return 0; } prop_dictionary_t @@ -422,9 +347,11 @@ find_pkg_missing_deps_from_repo(prop_dictionary_t repo, prop_dictionary_t pkg) /* * Remove package from missing now. */ - rv = remove_missing_reqdep(pkgname); - if (rv != 0 && rv != ENOENT) - break; + if (!xbps_remove_pkg_from_dict(chaindeps, + "missing_deps", pkgname)) { + if (errno != 0 && errno != ENOENT) + break; + } prop_object_iterator_reset(iter); } @@ -521,10 +448,12 @@ find_pkg_deps_from_repo(prop_dictionary_t repo, prop_dictionary_t pkg, /* * Remove package from missing_deps now it's been found. */ - rv = remove_missing_reqdep(pkgname); - if (rv != 0 && rv != ENOENT) { - free(pkgname); - break; + if (!xbps_remove_pkg_from_dict(chaindeps, + "missing_deps", pkgname)) { + if (errno != 0 && errno != ENOENT) { + free(pkgname); + break; + } } free(pkgname); diff --git a/lib/install.c b/lib/install.c index 4faf3a7a7ef..765968f0ba6 100644 --- a/lib/install.c +++ b/lib/install.c @@ -34,13 +34,6 @@ #include -struct binpkg_instargs { - const char *pkgname; - bool update; -}; - -static int install_binpkg_repo_cb(prop_object_t, void *, bool *); - int xbps_install_binary_pkg_fini(prop_dictionary_t repo, prop_dictionary_t pkgrd, bool update) @@ -96,69 +89,88 @@ xbps_install_binary_pkg_fini(prop_dictionary_t repo, prop_dictionary_t pkgrd, int xbps_install_binary_pkg(const char *pkgname, bool update) { - struct binpkg_instargs bi; - int rv = 0; - - assert(pkgname != NULL); - - bi.pkgname = pkgname; - bi.update = update; - /* - * Iterate over the repository pool and find out if we have - * all available binary packages. - */ - rv = xbps_callback_array_iter_in_repolist(install_binpkg_repo_cb, - (void *)&bi); - if (rv == 0 && errno != 0) - return errno; - - return rv; -} - -static int -install_binpkg_repo_cb(prop_object_t obj, void *arg, bool *cbloop_done) -{ - prop_dictionary_t repod, pkgrd; - struct binpkg_instargs *bi = arg; + prop_dictionary_t repod = NULL, repolistd, pkgrd = NULL; + prop_array_t array; + prop_object_t obj; + prop_object_iterator_t repolist_iter; size_t len = 0; const char *repoloc, *instver; char *plist, *pkg; int rv = 0; - plist = xbps_get_pkg_index_plist(prop_string_cstring_nocopy(obj)); + assert(pkgname != NULL); + + plist = xbps_append_full_path(true, NULL, XBPS_REPOLIST); if (plist == NULL) return EINVAL; - repod = prop_dictionary_internalize_from_file(plist); - if (repod == NULL) { - free(plist); - return errno; + repolistd = prop_dictionary_internalize_from_file(plist); + if (repolistd == NULL) { + free(plist); + return EINVAL; } free(plist); + plist = NULL; + + array = prop_dictionary_get(repolistd, "repository-list"); + if (array == NULL) { + prop_object_release(repolistd); + return EINVAL; + } + + repolist_iter = prop_array_iterator(array); + if (repolist_iter == NULL) { + prop_object_release(repolistd); + return ENOMEM; + } + + while ((obj = prop_object_iterator_next(repolist_iter)) != NULL) { + /* + * Iterate over the repository pool and find out if we have + * the binary package. + */ + plist = + xbps_get_pkg_index_plist(prop_string_cstring_nocopy(obj)); + if (plist == NULL) + return EINVAL; + + repod = prop_dictionary_internalize_from_file(plist); + if (repod == NULL) { + free(plist); + return errno; + } + free(plist); + + /* + * Get the package dictionary from current repository. + * If it's not there, pass to the next repository. + */ + pkgrd = xbps_find_pkg_in_dict(repod, "packages", pkgname); + if (pkgrd == NULL) { + prop_object_release(repod); + continue; + } + break; + } + prop_object_iterator_reset(repolist_iter); - /* - * Get the package dictionary from current repository. - * If it's not there, pass to the next repository. - */ - pkgrd = xbps_find_pkg_in_dict(repod, "packages", bi->pkgname); if (pkgrd == NULL) { - prop_object_release(repod); - errno = EAGAIN; - return 0; + rv = EAGAIN; + goto out2; } /* - * Check if available version in repository is already installed, - * and return immediately in that case. + * Check if available version in repository is already + * installed, and return immediately in that case. */ prop_dictionary_get_cstring_nocopy(pkgrd, "version", &instver); - len = strlen(bi->pkgname) + strlen(instver) + 2; + len = strlen(pkgname) + strlen(instver) + 2; pkg = malloc(len); if (pkg == NULL) { - rv = EINVAL; + rv = errno; goto out; } - (void)snprintf(pkg, len, "%s-%s", bi->pkgname, instver); + (void)snprintf(pkg, len, "%s-%s", pkgname, instver); if (xbps_check_is_installed_pkg(pkg) == 0) { free(pkg); rv = EEXIST; @@ -169,10 +181,10 @@ install_binpkg_repo_cb(prop_object_t obj, void *arg, bool *cbloop_done) /* * Check SHA256 hash for binary package before anything else. */ - if (!prop_dictionary_get_cstring_nocopy(repod, "location-local", - &repoloc)) { - prop_object_release(repod); - return EINVAL; + if (!prop_dictionary_get_cstring_nocopy(repod, + "location-local", &repoloc)) { + rv = EINVAL; + goto out; } if ((rv = xbps_check_pkg_file_hash(pkgrd, repoloc)) != 0) @@ -181,41 +193,32 @@ install_binpkg_repo_cb(prop_object_t obj, void *arg, bool *cbloop_done) /* * Check if this package needs dependencies. */ - if (!xbps_pkg_has_rundeps(pkgrd)) { - /* pkg has no deps, just install it. */ - goto install; + if (xbps_pkg_has_rundeps(pkgrd)) { + /* + * Construct the dependency chain for this package. + */ + printf("Finding required dependencies...\n"); + if ((rv = xbps_find_deps_in_pkg(pkgrd, repolist_iter)) != 0) + goto out; + + /* + * Install all required dependencies and the package itself. + */ + rv = xbps_install_pkg_deps(pkgname, update); + if (rv != 0) + goto out; } /* - * Construct the dependency chain for this package. + * Finally install the binary package that was requested by + * the client. */ - printf("Finding required dependencies...\n"); - if ((rv = xbps_find_deps_in_pkg(pkgrd)) != 0) { - prop_object_release(repod); - if (rv == ENOENT) { - errno = ENOENT; - return 0; - } - return rv; - } - - /* - * Install all required dependencies and the package itself. - */ - rv = xbps_install_pkg_deps(bi->pkgname, bi->update); - if (rv != 0) - goto out; - -install: - rv = xbps_install_binary_pkg_fini(repod, pkgrd, bi->update); - if (rv == 0) { - *cbloop_done = true; - /* Cleanup errno, just in case */ - errno = 0; - } - + rv = xbps_install_binary_pkg_fini(repod, pkgrd, update); out: prop_object_release(repod); +out2: + prop_object_iterator_release(repolist_iter); + prop_object_release(repolistd); return rv; } diff --git a/lib/plist.c b/lib/plist.c index 2f749f77954..0c3ed0d6ff3 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -238,7 +238,8 @@ xbps_get_array_iter_from_dict(prop_dictionary_t dict, const char *key) } bool -xbps_remove_pkg_from_dict(prop_dictionary_t dict, const char *pkgname) +xbps_remove_pkg_from_dict(prop_dictionary_t dict, const char *key, + const char *pkgname) { prop_array_t array; prop_object_t obj; @@ -251,7 +252,7 @@ xbps_remove_pkg_from_dict(prop_dictionary_t dict, const char *pkgname) assert(key != NULL); assert(pkgname != NULL); - array = prop_dictionary_get(dict, "packages"); + array = prop_dictionary_get(dict, key); if (array == NULL || prop_object_type(array) != PROP_TYPE_ARRAY) return false; @@ -272,6 +273,8 @@ xbps_remove_pkg_from_dict(prop_dictionary_t dict, const char *pkgname) prop_object_iterator_release(iter); if (found == true) prop_array_remove(array, i); + else + errno = ENOENT; return found; } @@ -288,7 +291,7 @@ xbps_remove_pkg_dict_from_file(const char *pkg, const char *plist) if (pdict == NULL) return false; - if (!xbps_remove_pkg_from_dict(pdict, pkg)) { + if (!xbps_remove_pkg_from_dict(pdict, "packages", pkg)) { prop_object_release(pdict); errno = ENODEV; return false; diff --git a/lib/sortdeps.c b/lib/sortdeps.c index 8419dc48b9f..5e3a9a2686d 100644 --- a/lib/sortdeps.c +++ b/lib/sortdeps.c @@ -103,7 +103,7 @@ again: if (find_sorteddep_by_name(pkgname) != NULL) continue; - sdep = calloc(1, sizeof(*sdep)); + sdep = malloc(sizeof(*sdep)); if (sdep == NULL) { rv = ENOMEM; goto out; diff --git a/lib/unpack.c b/lib/unpack.c index e5a53f03292..bee41a25ac2 100644 --- a/lib/unpack.c +++ b/lib/unpack.c @@ -212,8 +212,7 @@ unpack_archive_fini(struct archive *ar, prop_dictionary_t pkg) if (archive_read_extract(ar, entry, lflags) != 0) { rv = archive_errno(ar); if (rv != EEXIST) { - printf("ERROR: couldn't unpack %s (%s), " - "exiting!\n", archive_entry_pathname(entry), + printf("ERROR: %s...exiting!\n", archive_error_string(ar)); (void)fflush(stdout); break;