From 74d58d1b635413a97a3184996c3641fea9674f9e Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 5 Dec 2017 17:34:01 -0600 Subject: [PATCH] libpkgconf: pkg: cache solutions for already solved dependency graph nodes in almost all cases, we partially solve the dependency graph multiple times, which just wastes resources. if we record the solution to a given dependency node, further iterations can make use of the previous solution without having to solve it again. this is safe because all provides entries (including virtuals) are knowable prior to solving the dependency graph the first time. a nice side effect of this is that all packages are preloaded when querying information about them (--cflags and related commands). --- libpkgconf/dependency.c | 3 +++ libpkgconf/libpkgconf.h | 1 + libpkgconf/pkg.c | 18 +++++++++++++----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/libpkgconf/dependency.c b/libpkgconf/dependency.c index 1a4ec68..cd01a06 100644 --- a/libpkgconf/dependency.c +++ b/libpkgconf/dependency.c @@ -132,6 +132,9 @@ pkgconf_dependency_free(pkgconf_list_t *list) { pkgconf_dependency_t *dep = node->data; + if (dep->match != NULL) + pkgconf_pkg_unref(NULL, dep->match); + if (dep->package != NULL) free(dep->package); diff --git a/libpkgconf/libpkgconf.h b/libpkgconf/libpkgconf.h index 30f52a7..85d6ae2 100644 --- a/libpkgconf/libpkgconf.h +++ b/libpkgconf/libpkgconf.h @@ -87,6 +87,7 @@ struct pkgconf_dependency_ { pkgconf_pkg_comparator_t compare; char *version; pkgconf_pkg_t *parent; + pkgconf_pkg_t *match; }; struct pkgconf_tuple_ { diff --git a/libpkgconf/pkg.c b/libpkgconf/pkg.c index f883623..0e8c39f 100644 --- a/libpkgconf/pkg.c +++ b/libpkgconf/pkg.c @@ -1273,6 +1273,12 @@ pkgconf_pkg_verify_dependency(pkgconf_client_t *client, pkgconf_dependency_t *pk PKGCONF_TRACE(client, "trying to verify dependency: %s", pkgdep->package); + if (pkgdep->match != NULL) + { + PKGCONF_TRACE(client, "cached dependency: %s -> %s@%p", pkgdep->package, pkgdep->match->id, pkgdep->match); + return pkgconf_pkg_ref(client, pkgdep->match); + } + pkg = pkgconf_pkg_find(client, pkgdep->package); if (pkg == NULL) { @@ -1290,11 +1296,13 @@ pkgconf_pkg_verify_dependency(pkgconf_client_t *client, pkgconf_dependency_t *pk if (pkg->id == NULL) pkg->id = strdup(pkgdep->package); - if (pkgconf_pkg_comparator_impls[pkgdep->compare](pkg->version, pkgdep->version) == true) - return pkg; - - if (eflags != NULL) - *eflags |= PKGCONF_PKG_ERRF_PACKAGE_VER_MISMATCH; + if (pkgconf_pkg_comparator_impls[pkgdep->compare](pkg->version, pkgdep->version) != true) + { + if (eflags != NULL) + *eflags |= PKGCONF_PKG_ERRF_PACKAGE_VER_MISMATCH; + } + else + pkgdep->match = pkgconf_pkg_ref(client, pkg); return pkg; }