From b0fab7a3ee3ad3d6ef9f5518e78c1e3f63e711af Mon Sep 17 00:00:00 2001 From: Juan RP Date: Fri, 16 Nov 2012 21:50:52 +0100 Subject: [PATCH] Implemented a cache to get pkg dicts from metadir. This improves xbps-pkgdb -a marginally, but still seems to be a bit slow. --- bin/xbps-dgraph/main.c | 3 +- bin/xbps-pkgdb/check.c | 4 +- bin/xbps-pkgdb/check_pkg_requiredby.c | 21 ++--- bin/xbps-query/ownedby.c | 3 +- bin/xbps-query/show-deps.c | 3 +- bin/xbps-query/show-info-files.c | 11 +-- bin/xbps-uhelper/main.c | 2 +- include/xbps_api.h.in | 12 ++- include/xbps_api_impl.h | 3 + lib/Makefile | 2 +- lib/initend.c | 1 + lib/package_config_files.c | 4 +- lib/package_configure.c | 5 +- lib/package_metadir.c | 106 ++++++++++++++++++++++++++ lib/package_remove.c | 7 +- lib/plist.c | 37 --------- lib/transaction_dictionary.c | 3 +- 17 files changed, 139 insertions(+), 88 deletions(-) create mode 100644 lib/package_metadir.c diff --git a/bin/xbps-dgraph/main.c b/bin/xbps-dgraph/main.c index 493c9f95..9b2b74e7 100644 --- a/bin/xbps-dgraph/main.c +++ b/bin/xbps-dgraph/main.c @@ -510,7 +510,7 @@ main(int argc, char **argv) /* * Internalize the plist file of the target installed package. */ - plistd = xbps_pkgd_from_metadir(&xh, argv[0]); + plistd = xbps_metadir_get_pkgd(&xh, argv[0]); if (plistd == NULL) die("cannot internalize %s metadata file", argv[0]); @@ -525,7 +525,6 @@ main(int argc, char **argv) */ create_dot_graph(&xh, f, plistd, confd, revdeps); - prop_object_release(plistd); prop_object_release(confd); xbps_end(&xh); diff --git a/bin/xbps-pkgdb/check.c b/bin/xbps-pkgdb/check.c index 10aff9d8..696970e0 100644 --- a/bin/xbps-pkgdb/check.c +++ b/bin/xbps-pkgdb/check.c @@ -122,7 +122,7 @@ check_pkg_integrity(struct xbps_handle *xhp, /* * Check for props.plist metadata file. */ - propsd = xbps_pkgd_from_metadir(xhp, pkgname); + propsd = xbps_metadir_get_pkgd(xhp, pkgname); if (propsd == NULL) { printf("%s: unexistent metafile, converting to 0.18 " "format...\n", pkgname); @@ -183,8 +183,6 @@ out1: #undef RUN_PKG_CHECK out: - if (prop_object_type(propsd) == PROP_TYPE_DICTIONARY) - prop_object_release(propsd); if (broken) return 1; diff --git a/bin/xbps-pkgdb/check_pkg_requiredby.c b/bin/xbps-pkgdb/check_pkg_requiredby.c index 39294cda..0a5970a1 100644 --- a/bin/xbps-pkgdb/check_pkg_requiredby.c +++ b/bin/xbps-pkgdb/check_pkg_requiredby.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include "defs.h" @@ -65,7 +65,7 @@ check_reqby_pkg_cb(struct xbps_handle *xhp, * Internalize current pkg props dictionary from its * installed metadata directory. */ - curpkg_propsd = xbps_pkgd_from_metadir(xhp, curpkgn); + curpkg_propsd = xbps_metadir_get_pkgd(xhp, curpkgn); if (curpkg_propsd == NULL) { xbps_error_printf("%s: missing %s metadata file!\n", curpkgn, XBPS_PKGPROPS); @@ -75,7 +75,6 @@ check_reqby_pkg_cb(struct xbps_handle *xhp, prop_dictionary_get(curpkg_propsd, "run_depends"); if (curpkg_rdeps == NULL) { /* package has no rundeps, skip */ - prop_object_release(curpkg_propsd); return 0; } /* @@ -90,13 +89,11 @@ check_reqby_pkg_cb(struct xbps_handle *xhp, provides = prop_dictionary_get(obj, "provides"); if (provides == NULL) { /* doesn't provide any virtual pkg */ - prop_object_release(curpkg_propsd); return 0; } if (!xbps_match_any_virtualpkg_in_rundeps(curpkg_rdeps, provides)) { /* doesn't match any virtual pkg */ - prop_object_release(curpkg_propsd); return 0; } } @@ -113,7 +110,6 @@ check_reqby_pkg_cb(struct xbps_handle *xhp, * Current package already requires our package, * this is good so skip it. */ - prop_object_release(curpkg_propsd); return 0; } } else { @@ -121,22 +117,18 @@ check_reqby_pkg_cb(struct xbps_handle *xhp, * Missing requiredby array object, create it. */ crd->pkgd_reqby = prop_array_create(); - if (crd->pkgd_reqby == NULL) { - prop_object_release(curpkg_propsd); - return -1; - } + assert(crd->pkgd_reqby); crd->pkgd_reqby_alloc = true; } /* * Added pkgdep into pkg's requiredby array. */ - if (!prop_array_add(crd->pkgd_reqby, curpkgver)) { - prop_object_release(curpkg_propsd); + if (!prop_array_add(crd->pkgd_reqby, curpkgver)) return -1; - } + printf("%s: added missing requiredby entry for %s.\n\n", crd->pkgver, prop_string_cstring_nocopy(curpkgver)); - prop_object_release(curpkg_propsd); + return 1; } @@ -170,7 +162,6 @@ remove_stale_entries_in_reqby(struct xbps_handle *xhp, } if (needs_update) { prop_dictionary_set(crd->pkgd, "requiredby", crd->pkgd_reqby); - printf("%s: requiredby fix done!\n\n", crd->pkgver); return true; } return false; diff --git a/bin/xbps-query/ownedby.c b/bin/xbps-query/ownedby.c index 768cadd2..b241cccc 100644 --- a/bin/xbps-query/ownedby.c +++ b/bin/xbps-query/ownedby.c @@ -95,7 +95,7 @@ ownedby_pkgdb_cb(struct xbps_handle *xhp, prop_object_t obj, void *arg, bool *do (void)done; prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); - pkgmetad = xbps_pkgd_from_metadir(xhp, pkgname); + pkgmetad = xbps_metadir_get_pkgd(xhp, pkgname); files_keys = prop_dictionary_all_keys(pkgmetad); for (i = 0; i < prop_array_count(files_keys); i++) { @@ -106,7 +106,6 @@ ownedby_pkgdb_cb(struct xbps_handle *xhp, prop_object_t obj, void *arg, bool *do break; } prop_object_release(files_keys); - prop_object_release(pkgmetad); return rv; } diff --git a/bin/xbps-query/show-deps.c b/bin/xbps-query/show-deps.c index 117f8cb0..2786a1b4 100644 --- a/bin/xbps-query/show-deps.c +++ b/bin/xbps-query/show-deps.c @@ -44,13 +44,12 @@ show_pkg_deps(struct xbps_handle *xhp, const char *pkgname) /* * Check for props.plist metadata file. */ - propsd = xbps_pkgd_from_metadir(xhp, pkgname); + propsd = xbps_metadir_get_pkgd(xhp, pkgname); if (propsd == NULL) return ENOENT; rv = xbps_callback_array_iter_in_dict(xhp, propsd, "run_depends", list_strings_sep_in_array, NULL); - prop_object_release(propsd); return rv; } diff --git a/bin/xbps-query/show-info-files.c b/bin/xbps-query/show-info-files.c index 3883865d..7873e5f3 100644 --- a/bin/xbps-query/show-info-files.c +++ b/bin/xbps-query/show-info-files.c @@ -220,16 +220,15 @@ show_pkg_info_from_metadir(struct xbps_handle *xhp, const char *instdate, *pname; bool autoinst; - d = xbps_pkgd_from_metadir(xhp, pkgname); + d = xbps_metadir_get_pkgd(xhp, pkgname); if (d == NULL) return ENOENT; prop_dictionary_get_cstring_nocopy(d, "pkgname", &pname); pkgdb_d = xbps_pkgdb_get_pkgd(xhp, pname, false); - if (pkgdb_d == NULL) { - prop_object_release(d); + if (pkgdb_d == NULL) return EINVAL; - } + if (prop_dictionary_get_cstring_nocopy(pkgdb_d, "install-date", &instdate)) prop_dictionary_set_cstring_nocopy(d, "install-date", @@ -243,7 +242,6 @@ show_pkg_info_from_metadir(struct xbps_handle *xhp, else show_pkg_info_one(d, option); - prop_object_release(d); return 0; } @@ -253,12 +251,11 @@ show_pkg_files_from_metadir(struct xbps_handle *xhp, const char *pkgname) prop_dictionary_t d; int rv = 0; - d = xbps_pkgd_from_metadir(xhp, pkgname); + d = xbps_metadir_get_pkgd(xhp, pkgname); if (d == NULL) return ENOENT; rv = show_pkg_files(d); - prop_object_release(d); return rv; } diff --git a/bin/xbps-uhelper/main.c b/bin/xbps-uhelper/main.c index b4b9d565..6b98e01d 100644 --- a/bin/xbps-uhelper/main.c +++ b/bin/xbps-uhelper/main.c @@ -43,7 +43,7 @@ write_plist_file(prop_dictionary_t dict, const char *file) if (!prop_dictionary_externalize_to_zfile(dict, file)) { prop_object_release(dict); - xbps_error_printf("xbps-uhelper: couldn't write to %s: %s", + xbps_error_printf("xbps-uhelper: couldn't write to %s: %s\n", file, strerror(errno)); exit(EXIT_FAILURE); } diff --git a/include/xbps_api.h.in b/include/xbps_api.h.in index 70f6af67..ffc82fc0 100644 --- a/include/xbps_api.h.in +++ b/include/xbps_api.h.in @@ -56,7 +56,7 @@ */ #define XBPS_PKGINDEX_VERSION "1.5" -#define XBPS_API_VERSION "20121116" +#define XBPS_API_VERSION "20121116-1" #ifndef XBPS_VERSION #define XBPS_VERSION "UNSET" @@ -455,6 +455,12 @@ struct xbps_handle { * Array of dictionaries with all registered repositories. */ prop_array_t repo_pool; + /** + * @private + * + * Array of pkg dictionaries from metadir. + */ + prop_array_t metadir_pool; /** * @private pkgdb. * @@ -1213,8 +1219,8 @@ prop_object_iterator_t xbps_array_iter_from_dict(prop_dictionary_t dict, * @return The proplib dictionary on success, NULL otherwise and * errno is set appropiately. */ -prop_dictionary_t xbps_pkgd_from_metadir(struct xbps_handle *xhp, - const char *name); +prop_dictionary_t xbps_metadir_get_pkgd(struct xbps_handle *xhp, + const char *name); /** * Creates a temporary file and executes it in rootdir. diff --git a/include/xbps_api_impl.h b/include/xbps_api_impl.h index c36a3181..fdd7f7b9 100644 --- a/include/xbps_api_impl.h +++ b/include/xbps_api_impl.h @@ -182,6 +182,9 @@ int HIDDEN xbps_unpack_binary_pkg(struct xbps_handle *, prop_dictionary_t); */ void HIDDEN xbps_pkg_find_conflicts(struct xbps_handle *, prop_dictionary_t); +void HIDDEN xbps_metadir_init(struct xbps_handle *); +void HIDDEN xbps_metadir_release(struct xbps_handle *); + __END_DECLS #endif /* !_XBPS_API_IMPL_H_ */ diff --git a/lib/Makefile b/lib/Makefile index 933ae6bf..59778013 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -44,7 +44,7 @@ EXTOBJS += external/mkpath.o OBJS = package_configure.o package_config_files.o package_orphans.o OBJS += package_remove.o package_remove_obsoletes.o package_state.o OBJS += package_unpack.o package_requiredby.o package_register.o -OBJS += package_script.o +OBJS += package_script.o package_metadir.o OBJS += transaction_commit.o transaction_package_replace.o OBJS += transaction_dictionary.o transaction_sortdeps.o transaction_ops.o OBJS += download.o initend.o pkgdb.o package_conflicts.o diff --git a/lib/initend.c b/lib/initend.c index 6214d0e0..934ea8b2 100644 --- a/lib/initend.c +++ b/lib/initend.c @@ -232,6 +232,7 @@ xbps_end(struct xbps_handle *xhp) xbps_pkgdb_release(xhp); xbps_rpool_release(xhp); + xbps_metadir_release(xhp); xbps_fetch_unset_cache_connection(); cfg_free(xhp->cfg); diff --git a/lib/package_config_files.c b/lib/package_config_files.c index 9c590cbb..1f37f676 100644 --- a/lib/package_config_files.c +++ b/lib/package_config_files.c @@ -91,12 +91,11 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp, xbps_dbg_printf(xhp, "%s-%s: processing conf_file %s\n", pkgname, version, entry_pname); - forigd = xbps_pkgd_from_metadir(xhp, pkgname); + forigd = xbps_metadir_get_pkgd(xhp, pkgname); if (forigd == NULL) { xbps_dbg_printf(xhp, "%s-%s: conf_file %s not currently " "installed\n", pkgname, version, entry_pname); rv = 1; - prop_object_release(forigd); goto out; } @@ -117,7 +116,6 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp, } prop_object_iterator_release(iter2); } - prop_object_release(forigd); /* * First case: original hash not found, install new file. */ diff --git a/lib/package_configure.c b/lib/package_configure.c index d8868cef..7294f74e 100644 --- a/lib/package_configure.c +++ b/lib/package_configure.c @@ -110,7 +110,7 @@ xbps_configure_pkg(struct xbps_handle *xhp, xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE, 0, pkgname, version, NULL); - pkgmetad = xbps_pkgd_from_metadir(xhp, pkgname); + pkgmetad = xbps_metadir_get_pkgd(xhp, pkgname); assert(pkgmetad); rv = xbps_pkg_exec_script(xhp, pkgmetad, "install-script", "post", update); @@ -119,11 +119,8 @@ xbps_configure_pkg(struct xbps_handle *xhp, errno, pkgname, version, "%s: [configure] INSTALL script failed to execute " "the post ACTION: %s", pkgver, strerror(rv)); - prop_object_release(pkgmetad); return rv; } - prop_object_release(pkgmetad); - if (state == XBPS_PKG_STATE_INSTALLED) return rv; diff --git a/lib/package_metadir.c b/lib/package_metadir.c new file mode 100644 index 00000000..c6864a22 --- /dev/null +++ b/lib/package_metadir.c @@ -0,0 +1,106 @@ +/*- + * Copyright (c) 2012 Juan Romero Pardines. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "xbps_api_impl.h" + +void HIDDEN +xbps_metadir_init(struct xbps_handle *xhp) +{ + assert(xhp != NULL); + + if (xhp->metadir_pool != NULL) + return; + + xhp->metadir_pool = prop_array_create(); + assert(xhp->metadir_pool); +} + +void HIDDEN +xbps_metadir_release(struct xbps_handle *xhp) +{ + prop_object_t obj; + unsigned int i; + + if (xhp->metadir_pool == NULL) + return; + + for (i = 0; i < prop_array_count(xhp->metadir_pool); i++) { + obj = prop_array_get(xhp->metadir_pool, i); + prop_object_release(obj); + } + prop_object_release(xhp->metadir_pool); + xhp->metadir_pool = NULL; +} + +prop_dictionary_t +xbps_metadir_get_pkgd(struct xbps_handle *xhp, const char *name) +{ + prop_dictionary_t pkgd, opkgd; + const char *savedpkgname; + char *plistf; + + assert(xhp); + assert(name); + + xbps_metadir_init(xhp); + pkgd = xbps_find_pkg_in_array_by_name(xhp, xhp->metadir_pool, + name, NULL); + if (pkgd != NULL) + return pkgd; + + savedpkgname = name; + plistf = xbps_xasprintf("%s/.%s.plist", xhp->metadir, name); + + if (access(plistf, R_OK) == -1) { + pkgd = xbps_find_virtualpkg_dict_installed(xhp, name, false); + if (pkgd == NULL) + pkgd = xbps_find_pkg_dict_installed(xhp, name, false); + + if (pkgd != NULL) { + free(plistf); + prop_dictionary_get_cstring_nocopy(pkgd, + "pkgname", &savedpkgname); + plistf = xbps_xasprintf("%s/.%s.plist", + xhp->metadir, savedpkgname); + } + } + + opkgd = prop_dictionary_internalize_from_zfile(plistf); + free(plistf); + if (opkgd == NULL) { + xbps_dbg_printf(xhp, "cannot read %s metadata: %s\n", + savedpkgname, strerror(errno)); + return NULL; + } + + prop_array_add(xhp->metadir_pool, opkgd); + return opkgd; +} diff --git a/lib/package_remove.c b/lib/package_remove.c index a4ab3d7d..d5216fa3 100644 --- a/lib/package_remove.c +++ b/lib/package_remove.c @@ -238,7 +238,7 @@ xbps_remove_pkg(struct xbps_handle *xhp, pkgver, xhp->rootdir, strerror(rv)); goto out; } - pkgd = xbps_pkgd_from_metadir(xhp, pkgname); + pkgd = xbps_metadir_get_pkgd(xhp, pkgname); assert(pkgd); /* If package was "half-removed", remove it fully. */ @@ -341,9 +341,6 @@ purge: /* * Remove package metadata plist. */ - prop_object_release(pkgd); - pkgd = NULL; - buf = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname); if (remove(buf) == -1) { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL, @@ -373,8 +370,6 @@ out: free(buf); if (pkgver != NULL) free(pkgver); - if (pkgd != NULL) - prop_object_release(pkgd); return rv; } diff --git a/lib/plist.c b/lib/plist.c index d273b69c..f2288a99 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -264,40 +264,3 @@ xbps_array_replace_dict_by_pattern(prop_array_t array, { return array_replace_dict(array, dict, pattern, true); } - -prop_dictionary_t -xbps_pkgd_from_metadir(struct xbps_handle *xhp, const char *name) -{ - prop_dictionary_t pkgd, plistd = NULL; - const char *savedpkgname; - char *plistf; - - assert(name != NULL); - - savedpkgname = name; - plistf = xbps_xasprintf("%s/.%s.plist", xhp->metadir, name); - - if (access(plistf, R_OK) == -1) { - pkgd = xbps_find_virtualpkg_dict_installed(xhp, name, false); - if (pkgd == NULL) - pkgd = xbps_find_pkg_dict_installed(xhp, name, false); - - if (pkgd != NULL) { - free(plistf); - prop_dictionary_get_cstring_nocopy(pkgd, - "pkgname", &savedpkgname); - plistf = xbps_xasprintf("%s/.%s.plist", - xhp->metadir, savedpkgname); - } - } - - plistd = prop_dictionary_internalize_from_zfile(plistf); - free(plistf); - if (plistd == NULL) { - xbps_dbg_printf(xhp, "cannot read from metadata %s for %s: %s\n", - plistf, savedpkgname, strerror(errno)); - return NULL; - } - - return plistd; -} diff --git a/lib/transaction_dictionary.c b/lib/transaction_dictionary.c index 46beaa11..7788dcb5 100644 --- a/lib/transaction_dictionary.c +++ b/lib/transaction_dictionary.c @@ -97,12 +97,11 @@ compute_transaction_stats(struct xbps_handle *xhp) */ if ((strcmp(tract, "remove") == 0) || (strcmp(tract, "update") == 0)) { - pkg_metad = xbps_pkgd_from_metadir(xhp, pkgname); + pkg_metad = xbps_metadir_get_pkgd(xhp, pkgname); if (pkg_metad == NULL) continue; prop_dictionary_get_uint64(pkg_metad, "installed_size", &tsize); - prop_object_release(pkg_metad); rmsize += tsize; } if ((strcmp(tract, "install") == 0) ||