Commit 48d368e7 authored by Timo Teräs's avatar Timo Teräs

solver: move topology sorting to solver code

this allows quite some optimizations to running time and memory
requirements.
parent a5146f1b
......@@ -25,7 +25,7 @@ apk-objs := apk.o add.o del.o fix.o update.o info.o \
libapk.so-objs := common.o state.o database.o package.o archive.o \
version.o io.o url.o gunzip.o blob.o hash.o print.o \
solver.o topology.o
solver.o
ifeq ($(TEST),y)
progs-y += apk_test
......
......@@ -80,7 +80,10 @@ struct apk_installed_package {
struct apk_package {
apk_hash_node hash_node;
unsigned int topology_sort;
union {
int state_int;
void *state_ptr;
};
struct apk_name *name;
struct apk_installed_package *ipkg;
apk_blob_t *version, *arch, *license;
......
......@@ -53,16 +53,15 @@ static int dump_pkg(struct dot_ctx *ctx, struct apk_package *pkg)
{
int i, j, r, ret = 0;
/* Succesfully vandalize the apk_package by reusing
* size field for our evil purposes ;) */
if (pkg->size == S_EVALUATED)
if (pkg->state_int == S_EVALUATED)
return 0;
if (((ssize_t)pkg->size) <= S_EVALUATING) {
pkg->size--;
if (pkg->state_int <= S_EVALUATING) {
pkg->state_int--;
return 1;
}
pkg->size = S_EVALUATING;
pkg->state_int = S_EVALUATING;
for (i = 0; i < pkg->depends->num; i++) {
struct apk_dependency *dep = &pkg->depends->item[i];
struct apk_name *name = dep->name;
......@@ -96,8 +95,8 @@ static int dump_pkg(struct dot_ctx *ctx, struct apk_package *pkg)
}
}
}
ret -= S_EVALUATING - pkg->size;
pkg->size = S_EVALUATED;
ret -= S_EVALUATING - pkg->state_int;
pkg->state_int = S_EVALUATED;
return ret;
}
......
This diff is collapsed.
......@@ -179,7 +179,6 @@ static int test_main(void *pctx, struct apk_database *db, int argc, char **argv)
apk_deps_parse(db, &db->world, APK_BLOB_STR(argv[0]));
/* run solver */
apk_solver_sort(db);
r = apk_solver_solve(db, db->world, &solution, TRUE);
if (r == 0) {
memset(&changeset, 0, sizeof(changeset));
......
/* topology.c - Alpine Package Keeper (APK)
* Topological sorting of database packages
*
* Copyright (C) 2011 Timo Teräs <timo.teras@iki.fi>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation. See http://www.gnu.org/ for details.
*/
#include "apk_database.h"
static int sort_pkg(apk_hash_item item, void *ctx)
{
struct apk_package *pkg = (struct apk_package *) item;
unsigned int *sort_order = (unsigned int *) ctx;
int i, j;
/* Avoid recursion to same package */
if (pkg->topology_sort != 0) {
/* if pkg->topology_sort==-1 we have encountered a
* dependency loop. Just silently ignore it and pick a
* random topology sorting. */
return 0;
}
pkg->topology_sort = -1;
/* Sort all dependants before self */
for (i = 0; i < pkg->depends->num; i++) {
struct apk_dependency *dep = &pkg->depends->item[i];
struct apk_name *name0 = dep->name;
/* FIXME: sort names in order of ascending preference */
for (j = 0; j < name0->pkgs->num; j++) {
struct apk_package *pkg0 = name0->pkgs->item[j];
if (!apk_dep_is_satisfied(dep, pkg0))
continue;
sort_pkg(pkg0, ctx);
}
}
/* FIXME: install_if, provides, etc.*/
/* Finally assign a topology sorting order */
pkg->topology_sort = ++(*sort_order);
return 0;
}
void apk_solver_sort(struct apk_database *db)
{
unsigned int sort_order = 0;
apk_hash_foreach(&db->available.packages, sort_pkg, &sort_order);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment