From 831bce5cf90dea266f53a0d82c7371e4652c524c Mon Sep 17 00:00:00 2001
From: Timo Teräs <timo.teras@iki.fi>
Date: Mon, 8 Oct 2012 11:50:52 +0300
Subject: solver: properly calculate decision "strength" with provides

---
 src/solver.c | 30 +++++++++++++-----------------
 1 file changed, 13 insertions(+), 17 deletions(-)

(limited to 'src')

diff --git a/src/solver.c b/src/solver.c
index ac3200f..75a044b 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -80,7 +80,7 @@ struct apk_decision {
 	struct apk_score saved_score;
 	unsigned short saved_requirers;
 #endif
-
+	unsigned short requirers;
 	unsigned type : 1;
 	unsigned has_package : 1;
 	unsigned branching_point : 1;
@@ -885,6 +885,7 @@ static solver_result_t push_decision(struct apk_solver_state *ss,
 				     int topology_position)
 {
 	struct apk_decision *d;
+	int i;
 
 	ASSERT(ss->num_decisions <= ss->max_decisions,
 	       "Decision tree overflow.");
@@ -903,9 +904,12 @@ static solver_result_t push_decision(struct apk_solver_state *ss,
 	d->topology_position = topology_position;
 	d->found_solution = 0;
 	d->name = name;
+	d->requirers = name->ss.requirers;
 	if (pkg) {
 		d->has_package = 1;
 		d->pkg = pkg;
+		for (i = 0; i < pkg->provides->num; i++)
+			d->requirers += pkg->provides->item[i].name->ss.requirers;
 	} else {
 		d->has_package = 0;
 		d->backup_until = name->ss.last_touched_decision;
@@ -962,15 +966,13 @@ static int next_branch(struct apk_solver_state *ss)
 static void apply_constraint(struct apk_solver_state *ss, struct apk_dependency *dep)
 {
 	struct apk_package *requirer_pkg = NULL;
-	struct apk_name *name = dep->name, *requirer_name = NULL;
+	struct apk_name *name = dep->name;
 	int i, strength, changed = 0;
 
 	if (ss->num_decisions > 0) {
-		requirer_name = ss->decisions[ss->num_decisions].name;
-		requirer_pkg  = decision_to_pkg(&ss->decisions[ss->num_decisions]);
-		/* FIXME: should probably take into account the requirer
-		 * package's provided name's 'requirer strength' */
-		strength = requirer_name->ss.requirers ?: 1;
+		struct apk_decision *d = &ss->decisions[ss->num_decisions];
+		requirer_pkg  = decision_to_pkg(d);
+		strength      = d->requirers;
 	} else {
 		strength = 1;
 	}
@@ -1040,14 +1042,14 @@ static void apply_constraint(struct apk_solver_state *ss, struct apk_dependency
 
 static void undo_constraint(struct apk_solver_state *ss, struct apk_dependency *dep)
 {
-	struct apk_name *name = dep->name, *requirer_name = NULL;
+	struct apk_name *name = dep->name;
 	struct apk_package *requirer_pkg = NULL;
 	int i, strength;
 
 	if (ss->num_decisions > 0) {
-		requirer_name = ss->decisions[ss->num_decisions].name;
-		requirer_pkg  = decision_to_pkg(&ss->decisions[ss->num_decisions]);
-		strength = requirer_name->ss.requirers ?: 1;
+		struct apk_decision *d = &ss->decisions[ss->num_decisions];
+		requirer_pkg  = decision_to_pkg(d);
+		strength      = d->requirers;
 	} else {
 		strength = 1;
 	}
@@ -1104,12 +1106,6 @@ static void undo_constraint(struct apk_solver_state *ss, struct apk_dependency *
 	 * to store it (or hefty recalculations). */
 	name->ss.last_touched_decision = 0;
 
-	if (requirer_name && requirer_name->ss.requirers != strength) {
-		dbg_printf("requirer %s, dependency %s: strength mismatch %d != %d\n",
-			requirer_name->name, name->name,
-			requirer_name->ss.requirers, strength);
-	}
-
 	if (!dep->conflict) {
 		name->ss.requirers -= strength;
 		dbg_printf("%s requirers -= %d\n", name->name, strength);
-- 
cgit v1.2.3-70-g09d2