From 84bfef1a6b587a7da7d12fb701ab0d1d5d6ce2a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Mon, 29 Apr 2013 14:13:25 +0300 Subject: [PATCH] solver: increase score fields to 32-bits (from 16-bits) We are having so many packages that they might overflow otherwise. "ERROR: Preference overflow" was already reported. --- src/apk_solver_data.h | 22 ++++---------------- src/solver.c | 48 ++++++++++++++++++++++++------------------- 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/src/apk_solver_data.h b/src/apk_solver_data.h index 5777325..8076a08 100644 --- a/src/apk_solver_data.h +++ b/src/apk_solver_data.h @@ -17,24 +17,10 @@ #include "apk_provider_data.h" struct apk_score { - union { - struct { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - unsigned short preference; - unsigned short non_preferred_pinnings; - unsigned short non_preferred_actions; - unsigned short unsatisfied; -#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - unsigned short unsatisfied; - unsigned short non_preferred_actions; - unsigned short non_preferred_pinnings; - unsigned short preference; -#else -#error Unknown endianess. -#endif - }; - uint64_t score; - }; + uint32_t unsatisfied; + uint32_t non_preferred_actions; + uint32_t non_preferred_pinnings; + uint32_t preference; }; struct apk_solver_name_state { diff --git a/src/solver.c b/src/solver.c index d6ac1e1..f4d1f98 100644 --- a/src/solver.c +++ b/src/solver.c @@ -129,11 +129,15 @@ static solver_result_t push_decision(struct apk_solver_state *ss, int branching_point, int topology_position); -#ifdef DEBUG_CHECKS static void addscore(struct apk_score *a, struct apk_score *b) { struct apk_score orig = *a; - a->score += b->score; + + a->unsatisfied += b->unsatisfied; + a->non_preferred_actions += b->non_preferred_actions; + a->non_preferred_pinnings += b->non_preferred_pinnings; + a->preference += b->preference; + ASSERT(a->unsatisfied >= orig.unsatisfied, "Unsatisfied overflow"); ASSERT(a->non_preferred_actions >= orig.non_preferred_actions, "Preferred action overflow"); ASSERT(a->non_preferred_pinnings >= orig.non_preferred_pinnings, "Preferred pinning overflow"); @@ -143,38 +147,36 @@ static void addscore(struct apk_score *a, struct apk_score *b) static void subscore(struct apk_score *a, struct apk_score *b) { struct apk_score orig = *a; - a->score -= b->score; + + a->unsatisfied -= b->unsatisfied; + a->non_preferred_actions -= b->non_preferred_actions; + a->non_preferred_pinnings -= b->non_preferred_pinnings; + a->preference -= b->preference; + ASSERT(a->unsatisfied <= orig.unsatisfied, "Unsatisfied underflow"); ASSERT(a->non_preferred_actions <= orig.non_preferred_actions, "Preferred action underflow"); ASSERT(a->non_preferred_pinnings <= orig.non_preferred_pinnings, "Preferred pinning overflow"); ASSERT(a->preference <= orig.preference, "Preference underflow"); } -#else -static void addscore(struct apk_score *a, struct apk_score *b) -{ - a->score += b->score; -} - -static void subscore(struct apk_score *a, struct apk_score *b) -{ - a->score -= b->score; -} -#endif static inline int cmpscore(struct apk_score *a, struct apk_score *b) { - if (a->score < b->score) return -1; - if (a->score > b->score) return 1; + if (a->unsatisfied != b->unsatisfied) + return a->unsatisfied < b->unsatisfied ? -1 : 1; + if (a->non_preferred_actions != b->non_preferred_actions) + return a->non_preferred_actions < b->non_preferred_actions ? -1 : 1; + if (a->non_preferred_pinnings != b->non_preferred_pinnings) + return a->non_preferred_pinnings < b->non_preferred_pinnings ? -1 : 1; + if (a->preference != b->preference) + return a->preference < b->preference ? -1 : 1; return 0; } static inline int cmpscore2(struct apk_score *a1, struct apk_score *a2, struct apk_score *b) { - struct apk_score a; - a.score = a1->score + a2->score; - if (a.score < b->score) return -1; - if (a.score > b->score) return 1; - return 0; + struct apk_score a = *a1; + addscore(&a, a2); + return cmpscore(&a, b); } static struct apk_package_state *pkg_to_ps(struct apk_package *pkg) @@ -1986,6 +1988,10 @@ void apk_solver_print_errors(struct apk_database *db, char pkgtext[256]; int i, j; + /* negative for hard failure without partial solution */ + if (unsatisfiable <= 0) + return; + apk_name_array_init(&names); apk_error("%d unsatisfiable dependencies:", unsatisfiable);