summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2011-09-14 16:48:28 +0300
committerTimo Teräs <timo.teras@iki.fi>2011-09-14 16:48:28 +0300
commit803f55ece50bea9f0f8120dbcfe8068f689d3703 (patch)
treec7a8fc8a878b04f2eb1e861628c172c482b1bc4c
parent6b1a55825a3bd229d5ea343ed47ac36f6ca91062 (diff)
downloadapk-tools-803f55ece50bea9f0f8120dbcfe8068f689d3703.tar.gz
apk-tools-803f55ece50bea9f0f8120dbcfe8068f689d3703.tar.bz2
apk-tools-803f55ece50bea9f0f8120dbcfe8068f689d3703.tar.xz
apk-tools-803f55ece50bea9f0f8120dbcfe8068f689d3703.zip
solver: make state pointers completely internal
the only bit of information needed in solver commit is the "hard" topology sorting information for trigger ordering. fixes a bug in "apk del" which uses the state pointers to do intermediate calculations between solution solving and commit.
-rw-r--r--src/apk_package.h1
-rw-r--r--src/apk_solver.h2
-rw-r--r--src/del.c4
-rw-r--r--src/solver.c61
-rw-r--r--src/upgrade.c5
5 files changed, 32 insertions, 41 deletions
diff --git a/src/apk_package.h b/src/apk_package.h
index f752c87..b6bcffd 100644
--- a/src/apk_package.h
+++ b/src/apk_package.h
@@ -94,6 +94,7 @@ struct apk_package {
size_t installed_size, size;
time_t build_time;
unsigned repos;
+ unsigned int topology_hard;
struct apk_checksum csum;
};
APK_ARRAY(apk_package_array, struct apk_package *);
diff --git a/src/apk_solver.h b/src/apk_solver.h
index 3c14094..29961d0 100644
--- a/src/apk_solver.h
+++ b/src/apk_solver.h
@@ -25,7 +25,6 @@ struct apk_changeset {
#define APK_SOLVERF_UPGRADE 0x0001
#define APK_SOLVERF_AVAILABLE 0x0002
#define APK_SOLVERF_REINSTALL 0x0004
-#define APK_SOLVERF_KEEP_STATE 0x8000
void apk_solver_set_name_flags(struct apk_name *name,
unsigned short solver_flags);
@@ -34,7 +33,6 @@ int apk_solver_solve(struct apk_database *db,
struct apk_dependency_array *world,
struct apk_package_array **solution,
struct apk_changeset *changeset);
-void apk_solver_free(struct apk_database *db);
int apk_solver_commit_changeset(struct apk_database *db,
struct apk_changeset *changeset,
struct apk_dependency_array *world);
diff --git a/src/del.c b/src/del.c
index dff4356..3d7ffe7 100644
--- a/src/del.c
+++ b/src/del.c
@@ -142,8 +142,7 @@ static int del_main(void *pctx, struct apk_database *db, int argc, char **argv)
delete_from_world, ctx);
}
- r = apk_solver_solve(db, APK_SOLVERF_KEEP_STATE,
- ctx->world, &solution, &changeset);
+ r = apk_solver_solve(db, 0, ctx->world, &solution, &changeset);
if (r == 0 || (apk_flags & APK_FORCE)) {
/* check for non-deleted package names */
for (i = 0; i < solution->num; i++) {
@@ -167,7 +166,6 @@ static int del_main(void *pctx, struct apk_database *db, int argc, char **argv)
} else {
apk_solver_print_errors(db, solution, ctx->world, r);
}
- apk_solver_free(db);
apk_package_array_free(&solution);
apk_dependency_array_free(&ctx->world);
diff --git a/src/solver.c b/src/solver.c
index 349035a..b8dcc62 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -33,7 +33,7 @@
struct apk_package_state {
struct apk_package *backtrack;
- unsigned int topology_hard, topology_soft;
+ unsigned int topology_soft;
unsigned short flags;
unsigned short conflicts;
unsigned short cur_unsatisfiable;
@@ -158,17 +158,17 @@ static void sort_hard_dependencies(struct apk_solver_state *ss, struct apk_packa
pkg->state_ptr = calloc(1, sizeof(struct apk_package_state));
ps = pkg_to_ps(pkg);
- if (ps->topology_hard)
+ if (pkg->topology_hard)
return;
- ps->topology_hard = -1;
+ pkg->topology_hard = -1;
/* Consider hard dependencies only */
foreach_dependency_pkg(ss, pkg->depends, sort_hard_dependencies);
foreach_dependency_pkg(ss, pkg->install_if, sort_hard_dependencies);
- ps->topology_soft = ps->topology_hard = ++ss->num_topology_positions;
+ ps->topology_soft = pkg->topology_hard = ++ss->num_topology_positions;
dbg_printf(PKG_VER_FMT ": topology_hard=%d\n",
- PKG_VER_PRINTF(pkg), ps->topology_hard);
+ PKG_VER_PRINTF(pkg), pkg->topology_hard);
}
static void sort_soft_dependencies(struct apk_solver_state *ss, struct apk_package *pkg)
@@ -178,7 +178,7 @@ static void sort_soft_dependencies(struct apk_solver_state *ss, struct apk_packa
sort_hard_dependencies(ss, pkg);
ps = pkg_to_ps(pkg);
- if (ps->topology_soft != ps->topology_hard)
+ if (ps->topology_soft != pkg->topology_hard)
return;
ps->topology_soft = -1;
@@ -246,7 +246,7 @@ static int get_pkg_expansion_flags(struct apk_solver_state *ss, struct apk_packa
struct apk_package_state *ps0 = pkg_to_ps(pkg0);
if (pkg0 == pkg || ps0 == NULL ||
- ps0->topology_hard > ss->topology_position ||
+ pkg0->topology_hard > ss->topology_position ||
(ps0->flags & APK_PKGSTF_DECIDED) ||
ps0->conflicts != 0)
continue;
@@ -318,7 +318,7 @@ static int update_name_state(struct apk_solver_state *ss,
struct apk_package_state *ps0 = pkg_to_ps(pkg0);
if (ps0 == NULL ||
- ps0->topology_hard >= ss->topology_position ||
+ pkg0->topology_hard >= ss->topology_position ||
(ps0->flags & APK_PKGSTF_DECIDED))
continue;
@@ -332,8 +332,8 @@ static int update_name_state(struct apk_solver_state *ss,
if (ps0->topology_soft < ss->topology_position &&
ps0->topology_soft > best_topology)
best_pkg = pkg0, best_topology = ps0->topology_soft;
- else if (ps0->topology_hard > best_topology)
- best_pkg = pkg0, best_topology = ps0->topology_hard;
+ else if (pkg0->topology_hard > best_topology)
+ best_pkg = pkg0, best_topology = pkg0->topology_hard;
}
if (options == 0 && skipped_options == 0) {
@@ -434,7 +434,7 @@ static void undo_decision(struct apk_solver_state *ss,
if (ps->flags & APK_PKGSTF_INSTALLIF)
ss->topology_position = ps->topology_soft;
else
- ss->topology_position = ps->topology_hard;
+ ss->topology_position = pkg->topology_hard;
if (ps->flags & APK_PKGSTF_INSTALL) {
ss->assigned_names--;
@@ -465,7 +465,7 @@ static void push_decision(struct apk_solver_state *ss, struct apk_package *pkg,
ss->topology_position = ps->topology_soft;
} else {
ps->flags &= ~APK_PKGSTF_INSTALLIF;
- ss->topology_position = ps->topology_hard;
+ ss->topology_position = pkg->topology_hard;
}
ss->latest_decision = pkg;
@@ -534,7 +534,7 @@ static void apply_constraint(struct apk_solver_state *ss, struct apk_dependency
struct apk_package_state *ps0 = pkg_to_ps(pkg0);
if (ps0 == NULL ||
- ps0->topology_hard >= ss->topology_position)
+ pkg0->topology_hard >= ss->topology_position)
continue;
if (!apk_dep_is_satisfied(dep, pkg0)) {
@@ -565,7 +565,7 @@ static void undo_constraint(struct apk_solver_state *ss, struct apk_dependency *
struct apk_package *pkg0 = name->pkgs->item[i];
struct apk_package_state *ps0 = pkg_to_ps(pkg0);
- if (ps0->topology_hard >= ss->topology_position)
+ if (pkg0->topology_hard >= ss->topology_position)
continue;
if (!apk_dep_is_satisfied(dep, pkg0)) {
@@ -597,8 +597,8 @@ static int expand_branch(struct apk_solver_state *ss)
if (pkg_to_ps(ns->chosen)->topology_soft < ss->topology_position &&
pkg_to_ps(ns->chosen)->topology_soft > topology0)
pkg0 = ns->chosen, topology0 = pkg_to_ps(pkg0)->topology_soft;
- else if (pkg_to_ps(ns->chosen)->topology_hard > topology0)
- pkg0 = ns->chosen, topology0 = pkg_to_ps(pkg0)->topology_hard;
+ else if (ns->chosen->topology_hard > topology0)
+ pkg0 = ns->chosen, topology0 = pkg0->topology_hard;
}
if (pkg0 == NULL) {
dbg_printf("expand_branch: list is empty (%d unsatisfied)\n",
@@ -660,8 +660,8 @@ static int compare_change(const void *p1, const void *p2)
if (c1->newpkg == NULL) {
if (c2->newpkg == NULL)
/* both deleted - reverse topology order */
- return pkg_to_ps(c2->oldpkg)->topology_hard -
- pkg_to_ps(c1->oldpkg)->topology_hard;
+ return c2->oldpkg->topology_hard -
+ c1->oldpkg->topology_hard;
/* c1 deleted, c2 installed -> c2 first*/
return -1;
@@ -670,8 +670,8 @@ static int compare_change(const void *p1, const void *p2)
/* c1 installed, c2 deleted -> c1 first*/
return 1;
- return pkg_to_ps(c1->newpkg)->topology_hard -
- pkg_to_ps(c2->newpkg)->topology_hard;
+ return c1->newpkg->topology_hard -
+ c2->newpkg->topology_hard;
}
static int generate_changeset(struct apk_database *db,
@@ -763,6 +763,12 @@ void apk_solver_set_name_flags(struct apk_name *name,
ns->solver_flags = solver_flags;
}
+static void apk_solver_free(struct apk_database *db)
+{
+ apk_hash_foreach(&db->available.names, free_state, NULL);
+ apk_hash_foreach(&db->available.packages, free_package, NULL);
+}
+
int apk_solver_solve(struct apk_database *db,
unsigned short solver_flags,
struct apk_dependency_array *world,
@@ -826,20 +832,12 @@ int apk_solver_solve(struct apk_database *db,
else
apk_package_array_free(&ss->best_solution);
- if (!(solver_flags & APK_SOLVERF_KEEP_STATE))
- apk_solver_free(db);
-
+ apk_solver_free(db);
free(ss);
return r;
}
-void apk_solver_free(struct apk_database *db)
-{
- apk_hash_foreach(&db->available.names, free_state, NULL);
- apk_hash_foreach(&db->available.packages, free_package, NULL);
-}
-
static void print_change(struct apk_database *db,
struct apk_change *change,
int cur, int total)
@@ -1013,7 +1011,7 @@ static int compare_package(const void *p1, const void *p2)
struct apk_package *pkg1 = *(struct apk_package **) p1;
struct apk_package *pkg2 = *(struct apk_package **) p2;
- return pkg_to_ps(pkg1)->topology_hard - pkg_to_ps(pkg2)->topology_hard;
+ return pkg1->topology_hard - pkg2->topology_hard;
}
static void run_triggers(struct apk_database *db)
@@ -1186,7 +1184,7 @@ int apk_solver_commit(struct apk_database *db,
struct apk_package_array *solution = NULL;
int r;
- r = apk_solver_solve(db, APK_SOLVERF_KEEP_STATE | solver_flags,
+ r = apk_solver_solve(db, solver_flags,
world, &solution, &changeset);
if (r < 0)
return r;
@@ -1200,7 +1198,6 @@ int apk_solver_commit(struct apk_database *db,
apk_solver_print_errors(db, solution, world, r);
}
apk_package_array_free(&solution);
- apk_solver_free(db);
return r;
}
diff --git a/src/upgrade.c b/src/upgrade.c
index 541fbf3..dd53c19 100644
--- a/src/upgrade.c
+++ b/src/upgrade.c
@@ -52,8 +52,7 @@ int apk_do_self_upgrade(struct apk_database *db, unsigned short solver_flags)
apk_solver_set_name_flags(name, solver_flags);
db->performing_self_update = 1;
- r = apk_solver_solve(db, APK_SOLVERF_KEEP_STATE,
- db->world, &solution, &changeset);
+ r = apk_solver_solve(db, 0, db->world, &solution, &changeset);
if (r != 0) {
if (apk_flags & APK_FORCE)
r = 0;
@@ -72,7 +71,6 @@ int apk_do_self_upgrade(struct apk_database *db, unsigned short solver_flags)
apk_message("Upgrading critical system libraries and apk-tools:");
apk_solver_commit_changeset(db, &changeset, db->world);
- apk_solver_free(db);
apk_db_close(db);
apk_message("Continuing the upgrade transaction with new apk-tools:");
@@ -85,7 +83,6 @@ int apk_do_self_upgrade(struct apk_database *db, unsigned short solver_flags)
exit(1);
ret:
- apk_solver_free(db);
apk_package_array_free(&solution);
apk_change_array_free(&changeset.changes);
db->performing_self_update = 0;