summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2013-04-29 14:13:25 +0300
committerTimo Teräs <timo.teras@iki.fi>2013-04-29 14:14:57 +0300
commit84bfef1a6b587a7da7d12fb701ab0d1d5d6ce2a9 (patch)
treefdd58afa69801d893f7840d44a6810e0cde87a88 /src
parent4c08eca3bb844ed51acab1461327f3dd01ce1866 (diff)
downloadapk-tools-84bfef1a6b587a7da7d12fb701ab0d1d5d6ce2a9.tar.gz
apk-tools-84bfef1a6b587a7da7d12fb701ab0d1d5d6ce2a9.tar.bz2
apk-tools-84bfef1a6b587a7da7d12fb701ab0d1d5d6ce2a9.tar.xz
apk-tools-84bfef1a6b587a7da7d12fb701ab0d1d5d6ce2a9.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/apk_solver_data.h22
-rw-r--r--src/solver.c48
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);