]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Implement extra evr comparison for linked packages
authorMichael Schroeder <mls@suse.de>
Fri, 11 Dec 2015 16:31:37 +0000 (17:31 +0100)
committerMichael Schroeder <mls@suse.de>
Fri, 11 Dec 2015 16:31:37 +0000 (17:31 +0100)
src/linkedpkg.c
src/linkedpkg.h
src/policy.c

index a636db5971cd837f3fc32390676a8c48191fd678..a009f6623a5cc82f76adc4b507b99b80dccbeb3a 100644 (file)
@@ -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
index 25894c9ab7fe3ecb6189f35b58c6c61083247779..44632808bc30b2f5c5b385fe65cc8ab26f4e6e4a 100644 (file)
@@ -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
index fadfcdae4d65546f7137c0ba676153365213b858..12ad771a812ed62f2714f5f0added8e3a1e4163c 100644 (file)
 #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;