pkg: implement a cache for packages and use it to break circular dependencies

pull/48/head
William Pitcock 2013-02-24 08:14:23 -06:00
parent d4cef5cad5
commit 14f3e1edd2
3 changed files with 40 additions and 2 deletions

34
pkg.c
View File

@ -140,6 +140,8 @@ pkg_get_parent_dir(pkg_t *pkg)
return buf; return buf;
} }
static pkg_t *pkg_cache = NULL;
/* /*
* pkg_new_from_file(filename, file) * pkg_new_from_file(filename, file)
* *
@ -236,6 +238,15 @@ pkg_free(pkg_t *pkg)
if (pkg == NULL || pkg->flags & PKG_PROPF_VIRTUAL) if (pkg == NULL || pkg->flags & PKG_PROPF_VIRTUAL)
return; return;
if (pkg->next != NULL)
pkg->next->prev = pkg->prev;
if (pkg->prev != NULL)
pkg->prev->next = pkg->next;
if (pkg == pkg_cache)
pkg_cache = pkg->next;
pkg_dependency_free(pkg->requires); pkg_dependency_free(pkg->requires);
pkg_dependency_free(pkg->requires_private); pkg_dependency_free(pkg->requires_private);
pkg_dependency_free(pkg->conflicts); pkg_dependency_free(pkg->conflicts);
@ -419,6 +430,21 @@ pkg_find(const char *name, unsigned int flags)
return pkg_new_from_file(name, f); return pkg_new_from_file(name, f);
} }
/* check cache */
if (!(flags & PKGF_NO_CACHE))
{
PKG_FOREACH_LIST_ENTRY(pkg_cache, pkg)
{
if (!strcmp(pkg->id, name))
{
pkg->flags |= PKG_PROPF_CACHED;
return pkg;
}
}
pkg = NULL;
}
/* PKG_CONFIG_PATH has to take precedence */ /* PKG_CONFIG_PATH has to take precedence */
env_path = getenv("PKG_CONFIG_PATH"); env_path = getenv("PKG_CONFIG_PATH");
if (env_path) if (env_path)
@ -456,6 +482,12 @@ pkg_find(const char *name, unsigned int flags)
#endif #endif
out: out:
if (!(flags & PKGF_NO_CACHE))
{
pkg->next = pkg_cache;
pkg_cache = pkg;
}
path_free(path, count); path_free(path, count);
return pkg; return pkg;
} }
@ -809,6 +841,8 @@ pkg_walk_list(pkg_dependency_t *deplist,
pkgdep = pkg_verify_dependency(node, flags, &eflags); pkgdep = pkg_verify_dependency(node, flags, &eflags);
if (eflags != PKG_ERRF_OK) if (eflags != PKG_ERRF_OK)
return pkg_report_graph_error(pkgdep, node, eflags); return pkg_report_graph_error(pkgdep, node, eflags);
if (pkgdep->flags & PKG_PROPF_CACHED)
continue;
eflags = pkg_traverse(pkgdep, func, data, depth - 1, flags); eflags = pkg_traverse(pkgdep, func, data, depth - 1, flags);
pkg_free(pkgdep); pkg_free(pkgdep);

4
pkg.h
View File

@ -80,8 +80,11 @@ typedef struct pkg_queue_ {
#define PKG_PROPF_NONE 0x0 #define PKG_PROPF_NONE 0x0
#define PKG_PROPF_VIRTUAL 0x1 #define PKG_PROPF_VIRTUAL 0x1
#define PKG_PROPF_CACHED 0x2
struct pkg_ { struct pkg_ {
pkg_t *prev, *next; /* for pkg_cache */
char *id; char *id;
char *filename; char *filename;
char *realname; char *realname;
@ -114,6 +117,7 @@ struct pkg_ {
#define PKGF_SKIP_ROOT_VIRTUAL 0x08 #define PKGF_SKIP_ROOT_VIRTUAL 0x08
#define PKGF_MERGE_PRIVATE_FRAGMENTS 0x10 #define PKGF_MERGE_PRIVATE_FRAGMENTS 0x10
#define PKGF_SKIP_CONFLICTS 0x20 #define PKGF_SKIP_CONFLICTS 0x20
#define PKGF_NO_CACHE 0x40
#define PKG_ERRF_OK 0x0 #define PKG_ERRF_OK 0x0
#define PKG_ERRF_PACKAGE_NOT_FOUND 0x1 #define PKG_ERRF_PACKAGE_NOT_FOUND 0x1

View File

@ -87,9 +87,9 @@ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --exists '' 'foo'; echo \$?" \
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs intermediary-1 intermediary-2" \ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs intermediary-1 intermediary-2" \
'-lintermediary-1 -lintermediary-2 -lfoo -lbar -lbaz' '-lintermediary-1 -lintermediary-2 -lfoo -lbar -lbaz'
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs circular-1" \ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs circular-1" \
'-lcircular-2 -lcircular-3 -lcircular-1'
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs circular-3" \
'-lcircular-1 -lcircular-2 -lcircular-3' '-lcircular-1 -lcircular-2 -lcircular-3'
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs circular-3" \
'-lcircular-3 -lcircular-1 -lcircular-2'
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs static-archive-libs" \ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs static-archive-libs" \
'/libfoo.a -pthread' '/libfoo.a -pthread'