diff options
author | Dan Nicholson <dbn.lists@gmail.com> | 2013-01-16 16:42:48 -0800 |
---|---|---|
committer | Dan Nicholson <dbn.lists@gmail.com> | 2013-01-16 16:42:48 -0800 |
commit | ae2fef2c05bd7e875b4a84e584a183b027f53356 (patch) | |
tree | ac9103061515fa1f67d89e000bad89df34bf738c | |
parent | 4dac402b18f00cb9bf74b21631a073ae7acb04fc (diff) | |
download | pkg-config-ae2fef2c05bd7e875b4a84e584a183b027f53356.tar.gz |
Greatly simplify circular Requires checking
Instead of keeping of list of packages in the current Requires chain and
searching it repeatedly, just mark each package as part of the chain or
not. This nearly cuts in half the time on a particularly rough torture
test I have.
-rw-r--r-- | pkg.c | 7 | ||||
-rw-r--r-- | pkg.h | 1 |
2 files changed, 4 insertions, 4 deletions
@@ -606,7 +606,6 @@ static void recursive_fill_list (Package *pkg, GetListFunc func, GList **listp) { GList *tmp; - static GList *chain = NULL; /* * This function should only be called to resolve Requires or @@ -618,7 +617,7 @@ recursive_fill_list (Package *pkg, GetListFunc func, GList **listp) * If the package is one of the parents, we can skip it. This allows * circular requires loops to be broken. */ - if (g_list_find (chain, pkg) != NULL) + if (pkg->in_requires_chain) { debug_spew ("Package %s already in requires chain, skipping\n", pkg->key); @@ -626,7 +625,7 @@ recursive_fill_list (Package *pkg, GetListFunc func, GList **listp) } /* record this package in the dependency chain */ - chain = g_list_prepend (chain, pkg); + pkg->in_requires_chain = TRUE; /* Start from the end of the required package list to maintain order since * the recursive list is built by prepending. */ @@ -637,7 +636,7 @@ recursive_fill_list (Package *pkg, GetListFunc func, GList **listp) *listp = g_list_prepend (*listp, pkg); /* remove this package from the dependency chain now that we've unwound */ - chain = g_list_remove (chain, pkg); + pkg->in_requires_chain = FALSE; } /* merge the flags from the individual packages */ @@ -80,6 +80,7 @@ struct _Package int path_position; /* used to order packages by position in path of their .pc file, lower number means earlier in path */ int libs_num; /* Number of times the "Libs" header has been seen */ int libs_private_num; /* Number of times the "Libs.private" header has been seen */ + gboolean in_requires_chain; /* package is in current Requires chain */ }; Package *get_package (const char *name); |