implemented GNADENLOS in a better way, now option "noupdateprovide".
authorMichael Schroeder <mls@suse.de>
Mon, 15 Oct 2007 15:00:45 +0000 (15:00 +0000)
committerMichael Schroeder <mls@suse.de>
Mon, 15 Oct 2007 15:00:45 +0000 (15:00 +0000)
src/pool.c
src/solver.c
src/solver.h

index 8c892590f66ff22cf2e6434d38c4fe95ff8b8d39..4f60307115368da5be95926d611ef1ba975d005d 100644 (file)
@@ -154,8 +154,7 @@ pool_prepare(Pool *pool)
   whatprovides = (Offset *)xcalloc(num, sizeof(Offset));
 
   /* count providers for each name */
-
-  for (i = 1; i < pool->nsolvables; i++)   /* loop over all, but first, solvables */
+  for (i = 1; i < pool->nsolvables; i++)
     {
       Id *pp;
       s = pool->solvables + i;
index dba72dfab197dc38b99b1ac99ec538197edd3e06..6c676f306477bfe57b0398c81051ce37f0378ad4 100644 (file)
@@ -956,35 +956,6 @@ findupdatepackages(Solver *solv, Solvable *s, Queue *qs, Map *m, int allowdowngr
   if (m && !MAPTST(m, n))      /* add rule for s if not already done */
     addrulesforsolvable(solv, s, m);
 
-#if defined(GNADENLOS)
-  for (p = 1; p < pool->nsolvables; ++p)
-    {
-       if (p == n)
-        continue;
-
-       if (s->name == pool->solvables[p].name) 
-         continue;
-
-       if ((obsp = pool->solvables[p].obsoletes) != 0)   /* provides/obsoletes combination ? */
-        {
-          while ((obs = *obsp++) != 0)  /* for all obsoletes */
-            {
-              FOR_PROVIDES(p2, pp2, obs)   /* and all matching providers of the obsoletes */
-                {
-                  if (p2 == n)          /* match ! */
-                    break;
-                }
-              if (p2)                   /* match! */
-                break;
-            }
-          if (!obs)                     /* continue if no match */
-            continue;
-     
-         queuepush(qs, p); 
-       }
-    }
-#endif
-
   /*
    * look for updates for s
    */
@@ -1002,8 +973,7 @@ findupdatepackages(Solver *solv, Solvable *s, Queue *qs, Map *m, int allowdowngr
          if (!allowarchchange && archchanges(pool, s, pool->solvables + p))
            continue;
        }
-#if !defined(GNADENLOS)
-      else if ((obsp = pool->solvables[p].obsoletes) != 0)   /* provides/obsoletes combination ? */
+      else if (!solv->noupdateprovide && (obsp = pool->solvables[p].obsoletes) != 0)   /* provides/obsoletes combination ? */
        {
          while ((obs = *obsp++) != 0)  /* for all obsoletes */
            {
@@ -1021,7 +991,6 @@ findupdatepackages(Solver *solv, Solvable *s, Queue *qs, Map *m, int allowdowngr
           * thus flagging p as a valid update candidate for s
           */
        }
-#endif
       else
         continue;
       queuepush(qs, p);
@@ -1029,6 +998,15 @@ findupdatepackages(Solver *solv, Solvable *s, Queue *qs, Map *m, int allowdowngr
       if (m && !MAPTST(m, p))          /* mark p for install if not already done */
        addrulesforsolvable(solv, pool->solvables + p, m);
     }
+  if (solv->noupdateprovide && solv->obsoletes && solv->obsoletes[n - solv->system->start])
+    {
+      for (pp = solv->obsoletes_data + solv->obsoletes[n - solv->system->start]; (p = *pp++) != 0;)
+       {
+         queuepush(qs, p);
+         if (m && !MAPTST(m, p))               /* mark p for install if not already done */
+           addrulesforsolvable(solv, pool->solvables + p, m);
+       }
+    }
 }
 
 /*
@@ -1751,6 +1729,8 @@ solver_free(Solver *solv)
   xfree(solv->rules);
   xfree(solv->watches);
   xfree(solv->weaksystemrules);
+  xfree(solv->obsoletes);
+  xfree(solv->obsoletes_data);
   xfree(solv);
 }
 
@@ -2411,6 +2391,59 @@ printdecisions(Solver *solv)
   xfree(obsoletesmap);
 }
 
+static void
+create_obsolete_index(Solver *solv)
+{
+  Pool *pool = solv->pool;
+  Solvable *s;
+  Source *system = solv->system;
+  Id p, *pp, obs, *obsp, *obsoletes, *obsoletes_data;
+  int i, n;
+
+  /* create reverse obsoletes map for system solvables */
+  solv->obsoletes = obsoletes = xcalloc(system->nsolvables, sizeof(Id));
+  for (i = 1; i < pool->nsolvables; i++)
+    {
+      s = pool->solvables + i;
+      if ((obsp = s->obsoletes) == 0)
+       continue;
+      while ((obs = *obsp++) != 0)
+        FOR_PROVIDES(p, pp, obs)
+         {
+           if (p < system->start || p >= system->start + system->nsolvables)
+             continue;
+           if (pool->solvables[p].name == s->name)
+             continue;
+           obsoletes[p - system->start]++;
+         }
+    }
+  n = 0;
+  for (i = 0; i < system->nsolvables; i++)
+    if (obsoletes[i])
+      {
+        n += obsoletes[i] + 1;
+        obsoletes[i] = n;
+      }
+  solv->obsoletes_data = obsoletes_data = xcalloc(n + 1, sizeof(Id));
+  if (pool->verbose) printf("obsoletes data: %d entries\n", n + 1);
+  for (i = pool->nsolvables - 1; i > 0; i--)
+    {
+      s = pool->solvables + i;
+      if ((obsp = s->obsoletes) == 0)
+       continue;
+      while ((obs = *obsp++) != 0)
+        FOR_PROVIDES(p, pp, obs)
+         {
+           if (p < system->start || p >= system->start + system->nsolvables)
+             continue;
+           if (pool->solvables[p].name == s->name)
+             continue;
+           p -= system->start;
+           if (obsoletes_data[obsoletes[p]] != i)
+             obsoletes_data[--obsoletes[p]] = i;
+         }
+    }
+}
 
 /*-----------------------------------------------------------------*/
 /* main() */
@@ -2460,6 +2493,9 @@ solve(Solver *solv, Queue *job)
    * 
    */
 
+  if (solv->noupdateprovide && solv->system->nsolvables)
+    create_obsolete_index(solv);
+
   /*
    * solvable rules
    *  process job rules for solvables
index 7c8aa4efd98d1ae895cd9efad1e34a14a9dc2c29..602d10148b07330aa25744a08e5c15e7d0042969 100644 (file)
@@ -47,6 +47,7 @@ typedef struct solver {
   int allowuninstall;                  /* allow removal of system solvables, else keep all installed solvables */
   int updatesystem;                    /* distupgrade */
   int allowvirtualconflicts;           /* false: conflicts on package name, true: conflicts on package provides */
+  int noupdateprovide;                 /* true: update packages needs not to provide old package */
   
   Rule *rules;                         /* all rules */
   Id nrules;                           /* rpm rules */
@@ -80,6 +81,9 @@ typedef struct solver {
   Map suggests;                                /* suggested packages from decisionmap */
   int recommends_index;                        /* recommended level */
 
+  Id *obsoletes;                       /* obsoletes for each system solvable */
+  Id *obsoletes_data;                  /* data area for obsoletes */
+
   int rc_output;                       /* output result compatible to redcarpet/zypp testsuite, set == 2 for pure rc (will suppress architecture) */
 } Solver;