- bring solvable_trivial_installable functions back in sync with pool_trivial_installable
authorMichael Schroeder <mls@suse.de>
Wed, 21 Mar 2012 15:18:54 +0000 (16:18 +0100)
committerMichael Schroeder <mls@suse.de>
Wed, 21 Mar 2012 15:18:54 +0000 (16:18 +0100)
examples/solv.c
src/pool.h
src/solvable.c

index 75eb30d..49bc038 100644 (file)
@@ -2438,24 +2438,26 @@ static Id
 nscallback(Pool *pool, void *data, Id name, Id evr)
 {
   if (name == NAMESPACE_PRODUCTBUDDY)
-    {    
+    {
       /* SUSE specific hack: each product has an associated rpm */
-      Solvable *s = pool->solvables + evr; 
-      Id p, pp, cap; 
-      
+      Solvable *s = pool->solvables + evr;
+      Id p, pp, cap;
+      Id bestp = 0;
+
       cap = pool_str2id(pool, pool_tmpjoin(pool, "product(", pool_id2str(pool, s->name) + 8, ")"), 0);
       if (!cap)
         return 0;
       cap = pool_rel2id(pool, cap, s->evr, REL_EQ, 0);
       if (!cap)
         return 0;
-      FOR_PROVIDES(p, pp, cap) 
+      FOR_PROVIDES(p, pp, cap)
         {
-          Solvable *ps = pool->solvables + p; 
+          Solvable *ps = pool->solvables + p;
           if (ps->repo == s->repo && ps->arch == s->arch)
-            break;
+            if (!bestp || pool_evrcmp(pool, pool->solvables[bestp].evr, ps->evr, EVRCMP_COMPARE) < 0)
+             bestp = p;
         }
-      return p;
+      return bestp;
     }
   return 0;
 }
@@ -2573,10 +2575,12 @@ select_patches(Pool *pool, Queue *job)
 {
   Id p, pp;
   int pruneyou = 0;
-  Map installedmap;
+  Map installedmap, noobsmap;
   Solvable *s;
 
+  map_init(&noobsmap, 0);
   map_init(&installedmap, pool->nsolvables);
+  solver_calculate_noobsmap(pool, job, &noobsmap);
   if (pool->installed)
     FOR_REPO_SOLVABLES(pool->installed, p, s)
       MAPSET(&installedmap, p);
@@ -2605,7 +2609,7 @@ select_patches(Pool *pool, Queue *job)
       type = solvable_lookup_str(s, SOLVABLE_PATCHCATEGORY);
       if (type && !strcmp(type, "optional"))
        continue;
-      r = solvable_trivial_installable_map(s, &installedmap, 0);
+      r = solvable_trivial_installable_map(s, &installedmap, 0, &noobsmap);
       if (r == -1)
        continue;
       if (solvable_lookup_bool(s, UPDATE_RESTART) && r == 0)
@@ -2618,6 +2622,7 @@ select_patches(Pool *pool, Queue *job)
       queue_push2(job, SOLVER_SOLVABLE, p);
     }
   map_free(&installedmap);
+  map_free(&noobsmap);
 }
 
 #define MODE_LIST        0
@@ -3283,7 +3288,7 @@ rerunsolver:
              dataiterator_free(&di);
              solv_free(matchname);
            }
-         
+
          if (newpkgsfps[i])
            {
              putchar('d');
index 02f0be2..cbc8e1a 100644 (file)
@@ -241,9 +241,9 @@ static inline const char *pool_solvid2str(Pool *pool, Id p)
 void pool_set_languages(Pool *pool, const char **languages, int nlanguages);
 Id pool_id2langid(Pool *pool, Id id, const char *lang, int create);
 
-int solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap);
-int solvable_trivial_installable_repo(Solvable *s, struct _Repo *installed);
-int solvable_trivial_installable_queue(Solvable *s, Queue *installed);
+int solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap, Map *noobsoletesmap);
+int solvable_trivial_installable_repo(Solvable *s, struct _Repo *installed, Map *noobsoletesmap);
+int solvable_trivial_installable_queue(Solvable *s, Queue *installed, Map *noobsoletesmap);
 
 void pool_create_state_maps(Pool *pool, Queue *installed, Map *installedmap, Map *conflictsmap);
 
index a2d5389..cd9e863 100644 (file)
@@ -302,13 +302,37 @@ static inline Id dep2name(Pool *pool, Id dep)
   return dep;
 }
 
-static inline int providedbyinstalled(Pool *pool, Map *installed, Id dep)
+static int providedbyinstalled_multiversion(Pool *pool, Map *installed, Id n, Id con) 
+{
+  Id p, pp;
+  Solvable *sn = pool->solvables + n; 
+
+  FOR_PROVIDES(p, pp, sn->name)
+    {    
+      Solvable *s = pool->solvables + p; 
+      if (s->name != sn->name || s->arch != sn->arch)
+        continue;
+      if (!MAPTST(installed, p))
+        continue;
+      if (pool_match_nevr(pool, pool->solvables + p, con))
+        continue;
+      return 1;         /* found installed package that doesn't conflict */
+    }    
+  return 0;
+}
+
+static inline int providedbyinstalled(Pool *pool, Map *installed, Id dep, int ispatch, Map *noobsoletesmap)
 {
   Id p, pp;
   FOR_PROVIDES(p, pp, dep)
     {
       if (p == SYSTEMSOLVABLE)
        return -1;
+      if (ispatch && !pool_match_nevr(pool, pool->solvables + p, dep))
+       continue;
+      if (ispatch && noobsoletesmap && noobsoletesmap->size && MAPTST(noobsoletesmap, p) && ISRELDEP(dep))
+       if (providedbyinstalled_multiversion(pool, installed, p, dep))
+         continue;
       if (MAPTST(installed, p))
        return 1;
     }
@@ -332,14 +356,13 @@ static inline int providedbyinstalled(Pool *pool, Map *installed, Id dep)
  * -1: solvable is installable, but doesn't constrain any installed packages
  */
 int
-solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap)
+solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap, Map *noobsoletesmap)
 {
   Pool *pool = s->repo->pool;
   Solvable *s2;
-  Id p, pp, *dp;
+  Id p, *dp;
   Id *reqp, req;
   Id *conp, con;
-  Id *obsp, obs;
   int r, interesting = 0;
 
   if (conflictsmap && MAPTST(conflictsmap, s - pool->solvables))
@@ -351,7 +374,7 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm
        {
          if (req == SOLVABLE_PREREQMARKER)
            continue;
-          r = providedbyinstalled(pool, installedmap, req);
+          r = providedbyinstalled(pool, installedmap, req, 0, 0);
          if (!r)
            return 0;
          if (r > 0)
@@ -360,33 +383,40 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm
     }
   if (s->conflicts)
     {
+      int ispatch = 0;
+
+      if (!strncmp("patch:", pool_id2str(pool, s->name), 6))
+       ispatch = 1;
       conp = s->repo->idarraydata + s->conflicts;
       while ((con = *conp++) != 0)
        {
-         if (providedbyinstalled(pool, installedmap, con))
+         if (providedbyinstalled(pool, installedmap, con, ispatch, noobsoletesmap))
            return 0;
          if (!interesting && ISRELDEP(con))
            {
               con = dep2name(pool, con);
-             if (providedbyinstalled(pool, installedmap, con))
+             if (providedbyinstalled(pool, installedmap, con, ispatch, noobsoletesmap))
                interesting = 1;
            }
        }
     }
+#if 0
   if (s->repo)
     {
+      Id *obsp, obs;
       Repo *installed = 0;
       if (s->obsoletes && s->repo != installed)
        {
          obsp = s->repo->idarraydata + s->obsoletes;
          while ((obs = *obsp++) != 0)
            {
-             if (providedbyinstalled(pool, installedmap, obs))
+             if (providedbyinstalled(pool, installedmap, obs, 0, 0))
                return 0;
            }
        }
       if (s->repo != installed)
        {
+         Id pp;
          FOR_PROVIDES(p, pp, s->name)
            {
              s2 = pool->solvables + p;
@@ -395,6 +425,7 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm
            }
        }
     }
+#endif
   if (!conflictsmap)
     {
       int i;
@@ -426,7 +457,7 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm
  * by a queue.
  */
 int
-solvable_trivial_installable_queue(Solvable *s, Queue *installed)
+solvable_trivial_installable_queue(Solvable *s, Queue *installed, Map *noobsoletesmap)
 {
   Pool *pool = s->repo->pool;
   int i;
@@ -441,7 +472,7 @@ solvable_trivial_installable_queue(Solvable *s, Queue *installed)
       if (p > 0)               /* makes it work with decisionq */
        MAPSET(&installedmap, p);
     }
-  r = solvable_trivial_installable_map(s, &installedmap, 0);
+  r = solvable_trivial_installable_map(s, &installedmap, 0, noobsoletesmap);
   map_free(&installedmap);
   return r;
 }
@@ -452,7 +483,7 @@ solvable_trivial_installable_queue(Solvable *s, Queue *installed)
  * by a repo containing the installed solvables.
  */
 int
-solvable_trivial_installable_repo(Solvable *s, Repo *installed)
+solvable_trivial_installable_repo(Solvable *s, Repo *installed, Map *noobsoletesmap)
 {
   Pool *pool = s->repo->pool;
   Id p;
@@ -463,7 +494,7 @@ solvable_trivial_installable_repo(Solvable *s, Repo *installed)
   map_init(&installedmap, pool->nsolvables);
   FOR_REPO_SOLVABLES(installed, p, s2)
     MAPSET(&installedmap, p);
-  r = solvable_trivial_installable_map(s, &installedmap, 0);
+  r = solvable_trivial_installable_map(s, &installedmap, 0, noobsoletesmap);
   map_free(&installedmap);
   return r;
 }