summaryrefslogtreecommitdiffstats
path: root/main/apk-tools/0002-solver-fix-regression-from-calculate-branch-minimum-.patch
blob: f5975055ea7258ab09e117aed1da92be503e2279 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
From 0f895650996a2565c0dc59d3c94f861145b42c05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Fri, 20 Jan 2012 10:39:00 +0200
Subject: [PATCH 2/2] solver: fix regression from "calculate branch minimum
 penalty early"

Forgot to reset per-name penalty when it got locked by apply_decision.
This also fine tunes compare_package_preference() to always prefer
packages specified on command line speeding up calculation certain
complicated solutions.
---
 src/solver.c       |   28 +++++++++++++++++++++-------
 test/error2.expect |    3 +--
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/src/solver.c b/src/solver.c
index 76edeba..ba98ca6 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -325,6 +325,12 @@ static int compare_package_preference(unsigned short solver_flags,
 				      struct apk_package *pkgA,
 				      struct apk_package *pkgB)
 {
+	/* specified on command line directly */
+	if (pkgA->filename && !pkgB->filename)
+		return 1;
+	if (pkgB->filename && !pkgA->filename)
+		return -1;
+
 	if (solver_flags & APK_SOLVERF_PREFER_TAG) {
 		/* preferred repository pinning */
 		if ((pkgA->repos & preferred_repos) && !(pkgB->repos & preferred_repos))
@@ -333,11 +339,11 @@ static int compare_package_preference(unsigned short solver_flags,
 			return -1;
 	} else {
 		/* preferred repository pinning */
-		if ((pkgA->ipkg || pkgA->filename || (pkgA->repos & preferred_repos)) &&
-		    !(pkgB->ipkg || pkgB->filename || (pkgB->repos & preferred_repos)))
+		if ((pkgA->ipkg || (pkgA->repos & preferred_repos)) &&
+		    !(pkgB->ipkg || (pkgB->repos & preferred_repos)))
 			return 1;
-		if ((pkgB->ipkg || pkgA->filename || (pkgB->repos & preferred_repos)) &&
-		    !(pkgA->ipkg || pkgB->filename || (pkgA->repos & preferred_repos)))
+		if ((pkgB->ipkg || (pkgB->repos & preferred_repos)) &&
+		    !(pkgA->ipkg || (pkgA->repos & preferred_repos)))
 			return -1;
 	}
 
@@ -504,9 +510,6 @@ static int update_name_state(struct apk_solver_state *ss, struct apk_name *name)
 		dbg_printf("%s: deleted from unsolved: %d requirers, %d install_ifs, %d options, %d skipped\n",
 			   name->name, ns->requirers, ns->install_ifs, options, skipped_options);
 	} else {
-		dbg_printf("%s: added to unsolved: %d requirers, %d install_ifs, %d options (next topology %d)\n",
-			   name->name, ns->requirers, ns->install_ifs, options,
-			   best_topology);
 		if (!list_hashed(&ns->unsolved_list))
 			list_add(&ns->unsolved_list, &ss->unsolved_list_head);
 		if (!ns->locked) {
@@ -517,6 +520,11 @@ static int update_name_state(struct apk_solver_state *ss, struct apk_name *name)
 					.unsatisfiable = preferred_ps->conflicts,
 					.preference = get_preference(ss, preferred_pkg, FALSE),
 				};
+				dbg_printf("%s: min.penalty for name {%d, %d} from pkg " PKG_VER_FMT "\n",
+					   name->name,
+					   ns->minimum_penalty.unsatisfiable,
+					   ns->minimum_penalty.preference,
+					   PKG_VER_PRINTF(preferred_pkg));
 			} else {
 				ns->minimum_penalty = (struct apk_score) {
 					.unsatisfiable = ns->requirers,
@@ -525,6 +533,9 @@ static int update_name_state(struct apk_solver_state *ss, struct apk_name *name)
 			}
 			addscore(&ss->minimum_penalty, &ns->minimum_penalty);
 		}
+		dbg_printf("%s: added to unsolved: %d requirers, %d install_ifs, %d options (next topology %d)\n",
+			   name->name, ns->requirers, ns->install_ifs, options,
+			   best_topology);
 	}
 
 	return options + skipped_options;
@@ -568,6 +579,9 @@ static void apply_decision(struct apk_solver_state *ss,
 		   (ps->flags & APK_PKGSTF_INSTALL) ? "INSTALL" : "NO_INSTALL");
 
 	if (ps->flags & APK_PKGSTF_INSTALL) {
+		subscore(&ss->minimum_penalty, &ns->minimum_penalty);
+		ns->minimum_penalty = (struct apk_score) { 0, 0 };
+
 		ss->assigned_names++;
 		ss->score.unsatisfiable += ps->conflicts;
 		ss->score.preference += get_preference(ss, pkg, FALSE);
diff --git a/test/error2.expect b/test/error2.expect
index 65d0093..7faac5e 100644
--- a/test/error2.expect
+++ b/test/error2.expect
@@ -1,3 +1,2 @@
-2 unsatisfiable dependencies (solution with 4 names)
+1 unsatisfiable dependencies (solution with 4 names)
 world: d<1.5
-b-1: d<2.0
-- 
1.7.7.3