From 5536a9db66bfa81a43e6236cd6a600b271bd3b9f Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Fri, 11 Dec 2015 17:31:37 +0100 Subject: [PATCH] Implement extra evr comparison for linked packages --- src/linkedpkg.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ src/linkedpkg.h | 1 + src/policy.c | 17 +++++++------ 3 files changed, 78 insertions(+), 7 deletions(-) diff --git a/src/linkedpkg.c b/src/linkedpkg.c index a636db59..a009f662 100644 --- a/src/linkedpkg.c +++ b/src/linkedpkg.c @@ -37,6 +37,7 @@ #include "pool.h" #include "repo.h" +#include "evr.h" #include "linkedpkg.h" #ifdef ENABLE_LINKED_PKGS @@ -309,4 +310,70 @@ find_package_link(Pool *pool, Solvable *s, Id *reqidp, Queue *qr, Id *prvidp, Qu find_product_link(pool, s, reqidp, qr, prvidp, qp); } +static int +name_min_max(Pool *pool, Solvable *s, Id *namep, Id *minp, Id *maxp) +{ + Queue q; + Id qbuf[4]; + Id name, min, max; + int i; + + queue_init_buffer(&q, qbuf, sizeof(qbuf)/sizeof(*qbuf)); + find_package_link(pool, s, 0, &q, 0, 0); + if (!q.count) + { + queue_free(&q); + return 0; + } + s = pool->solvables + q.elements[0]; + name = s->name; + min = max = s->evr; + for (i = 1; i < q.count; i++) + { + s = pool->solvables + q.elements[i]; + if (s->name != name) + { + queue_free(&q); + return 0; + } + if (s->evr == min || s->evr == max) + continue; + if (pool_evrcmp(pool, min, s->evr, EVRCMP_COMPARE) >= 0) + min = s->evr; + else if (min == max || pool_evrcmp(pool, max, s->evr, EVRCMP_COMPARE) <= 0) + max = s->evr; + } + queue_free(&q); + *namep = name; + *minp = min; + *maxp = max; + return 1; +} + +int +pool_link_evrcmp(Pool *pool, Solvable *s1, Solvable *s2) +{ + Id name1, evrmin1, evrmax1; + Id name2, evrmin2, evrmax2; + + if (s1->name != s2->name) + return 0; /* can't compare */ + if (!name_min_max(pool, s1, &name1, &evrmin1, &evrmax1)) + return 0; + if (!name_min_max(pool, s2, &name2, &evrmin2, &evrmax2)) + return 0; + /* compare linked names */ + if (name1 != name2) + return 0; + /* now compare evr intervals */ + if (evrmin1 == evrmax1 && evrmin2 == evrmax2) + return pool_evrcmp(pool, evrmin1, evrmax2, EVRCMP_COMPARE); + if (evrmin1 != evrmax2 && pool_evrcmp(pool, evrmin1, evrmax2, EVRCMP_COMPARE) > 0) + return 1; + if (evrmax1 != evrmin2 && pool_evrcmp(pool, evrmax1, evrmin2, EVRCMP_COMPARE) < 0) + return -1; + return 0; +} + + #endif diff --git a/src/linkedpkg.h b/src/linkedpkg.h index 25894c9a..44632808 100644 --- a/src/linkedpkg.h +++ b/src/linkedpkg.h @@ -34,5 +34,6 @@ extern Id find_autoproduct_name(Pool *pool, Solvable *s); /* generic */ extern void find_package_link(Pool *pool, Solvable *s, Id *reqidp, Queue *qr, Id *prvidp, Queue *qp); +extern int pool_link_evrcmp(Pool *pool, Solvable *s1, Solvable *s2); #endif diff --git a/src/policy.c b/src/policy.c index fadfcdae..12ad771a 100644 --- a/src/policy.c +++ b/src/policy.c @@ -21,9 +21,11 @@ #include "policy.h" #include "poolvendor.h" #include "poolarch.h" +#include "linkedpkg.h" #include "cplxdeps.h" + /*-----------------------------------------------------------------*/ /* @@ -825,7 +827,7 @@ move_installed_to_front(Pool *pool, Queue *plist) void prune_to_best_version(Pool *pool, Queue *plist) { - int i, j; + int i, j, r; Solvable *s, *best; if (plist->count < 2) /* no need to prune for a single entry */ @@ -858,12 +860,13 @@ prune_to_best_version(Pool *pool, Queue *plist) best = s; /* take current as new best */ continue; } - - if (best->evr != s->evr) /* compare evr */ - { - if (pool_evrcmp(pool, best->evr, s->evr, EVRCMP_COMPARE) < 0) - best = s; - } + r = best->evr != s->evr ? pool_evrcmp(pool, best->evr, s->evr, EVRCMP_COMPARE) : 0; +#ifdef ENABLE_LINKED_PKGS + if (r == 0 && has_package_link(pool, s)) + r = pool_link_evrcmp(pool, best, s); +#endif + if (r < 0) + best = s; } plist->elements[j++] = best - pool->solvables; /* finish last group */ plist->count = j; -- 2.47.2