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).pull/164/head
parent
44b4b126f3
commit
74d58d1b63
|
@ -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);
|
||||
|
||||
|
|
|
@ -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_ {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue