From d420d4114863fadc6458b489cff32b3d3ab61349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Fri, 24 Feb 2012 11:13:31 +0200 Subject: [PATCH] solver: non preferred actions are worse then non preferred pinning Otherwise we might start to change packages unexpectedly when not upgrading. This also fixes some other things the solver might've decided to do. Add also few test cases to detect bad behaviour. --- src/solver.c | 22 ++++++++++++++++------ test/pinning.installed2 | 20 ++++++++++++++++++++ test/pinning8.test | 11 +++++++++++ test/pinning9.test | 8 ++++++++ 4 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 test/pinning.installed2 create mode 100644 test/pinning8.test create mode 100644 test/pinning9.test diff --git a/src/solver.c b/src/solver.c index d12ecff..f8bd4fd 100644 --- a/src/solver.c +++ b/src/solver.c @@ -39,11 +39,13 @@ struct apk_score { struct { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ unsigned short preference; + unsigned short non_preferred_pinnings; unsigned short non_preferred_actions; - unsigned int conflicts; + unsigned short conflicts; #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - unsigned int conflicts; + unsigned short conflicts; unsigned short non_preferred_actions; + unsigned short non_preferred_pinnings; unsigned short preference; #else #error Unknown endianess. @@ -53,8 +55,8 @@ struct apk_score { }; }; -#define SCORE_FMT "{%d/%d/%d}" -#define SCORE_PRINTF(s) (s)->conflicts, (s)->non_preferred_actions, (s)->preference +#define SCORE_FMT "{%d/%d/%d,%d}" +#define SCORE_PRINTF(s) (s)->conflicts, (s)->non_preferred_actions, (s)->non_preferred_pinnings, (s)->preference enum { DECISION_ASSIGN = 0, @@ -382,13 +384,21 @@ static int get_topology_score( preferred_repos = get_pinning_mask_repos(ss->db, preferred_pinning); if (!(repos & preferred_repos)) - score.non_preferred_actions++; + score.non_preferred_pinnings++; if (ns->locked || (ns->allowed_pinning | ns->maybe_pinning) == ns->allowed_pinning) { allowed_pinning = ns->allowed_pinning | preferred_pinning | APK_DEFAULT_PINNING_MASK; allowed_repos = get_pinning_mask_repos(ss->db, allowed_pinning); if (!(repos & allowed_repos)) - score.non_preferred_actions+=2; + score.non_preferred_pinnings += 16; + +#if 0 + if (allowed_pinning & ~APK_DEFAULT_PINNING_MASK) + fprintf(stdout, PKG_VER_FMT": allow: %x, in: %x, reallyin: %x. score="SCORE_FMT"\n", + PKG_VER_PRINTF(pkg), + allowed_repos, repos, pkg->repos, + SCORE_PRINTF(&score)); +#endif } else { score_locked = FALSE; } diff --git a/test/pinning.installed2 b/test/pinning.installed2 new file mode 100644 index 0000000..c41ddf7 --- /dev/null +++ b/test/pinning.installed2 @@ -0,0 +1,20 @@ +C:Q1eVpkasfqZAukAXFYbgwt4xffZWU= +P:a +V:3 +S:1 +I:1 +D:b + +C:Q1hdUpqRv5mYgJEqW52UmVsv23ysE= +P:b +V:3 +S:1 +I:1 + +C:Q1eVpkasfqZAukAXFYbg324xAt4WU= +P:c +V:3 +S:1 +I:1 +D:a>=3 + diff --git a/test/pinning8.test b/test/pinning8.test new file mode 100644 index 0000000..84f312b --- /dev/null +++ b/test/pinning8.test @@ -0,0 +1,11 @@ +@ARGS +--test-repo basic.repo +--test-repo testing:pinning.repo2 +--test-instdb pinning.installed2 +--test-world "c@testing" +upgrade -a +@EXPECT +(1/3) Downgrading b (3 -> 2) +(2/3) Upgrading a@testing (3 -> 3.1) +(3/3) Upgrading c@testing (3 -> 3.1) +OK: 0 MiB in 3 packages diff --git a/test/pinning9.test b/test/pinning9.test new file mode 100644 index 0000000..e9836ff --- /dev/null +++ b/test/pinning9.test @@ -0,0 +1,8 @@ +@ARGS +--test-repo basic.repo +--test-repo testing:pinning.repo2 +--test-instdb pinning.installed2 +--test-world "c@testing" +add +@EXPECT +OK: 0 MiB in 3 packages