- add solver_get_orphaned and solver_get_recommendations interface
authorMichael Schroeder <mls@suse.de>
Mon, 9 Jan 2012 16:55:05 +0000 (17:55 +0100)
committerMichael Schroeder <mls@suse.de>
Mon, 9 Jan 2012 16:55:05 +0000 (17:55 +0100)
src/libsolv.ver
src/solver.c
src/solver.h
src/solverdebug.c

index 4a0fc25..a3e7f26 100644 (file)
@@ -258,6 +258,8 @@ SOLV_1.0 {
                solver_get_decisionqueue;
                solver_get_flag;
                solver_get_lastdecisionblocklevel;
+               solver_get_orphaned;
+               solver_get_recommendations;
                solver_next_problem;
                solver_next_solution;
                solver_next_solutionelement;
index fd80677..9e39643 100644 (file)
@@ -1265,8 +1265,6 @@ solver_create(Pool *pool)
   queue_init(&solv->decisionq);
   queue_init(&solv->decisionq_why);
   queue_init(&solv->problems);
-  queue_init(&solv->suggestions);
-  queue_init(&solv->recommendations);
   queue_init(&solv->orphaned);
   queue_init(&solv->learnt_why);
   queue_init(&solv->learnt_pool);
@@ -1306,8 +1304,6 @@ solver_free(Solver *solv)
   queue_free(&solv->learnt_pool);
   queue_free(&solv->problems);
   queue_free(&solv->solutions);
-  queue_free(&solv->suggestions);
-  queue_free(&solv->recommendations);
   queue_free(&solv->orphaned);
   queue_free(&solv->branches);
   queue_free(&solv->weakruleq);
@@ -2330,216 +2326,6 @@ weaken_solvable_deps(Solver *solv, Id p)
 /* main() */
 
 
-static void
-solver_findrecommendedsuggested(Solver *solv)
-{
-  Pool *pool = solv->pool;
-  Queue redoq, disabledq;
-  int goterase, i;
-  Solvable *s;
-  Rule *r;
-  Map obsmap;
-
-  map_init(&obsmap, pool->nsolvables);
-  if (solv->installed)
-    {
-      Id obs, *obsp, p, po, ppo;
-      for (p = solv->installed->start; p < solv->installed->end; p++)
-       {
-         s = pool->solvables + p;
-         if (s->repo != solv->installed || !s->obsoletes)
-           continue;
-         if (solv->decisionmap[p] <= 0)
-           continue;
-         if (solv->noobsoletes.size && MAPTST(&solv->noobsoletes, p))
-           continue;
-         obsp = s->repo->idarraydata + s->obsoletes;
-         /* foreach obsoletes */
-         while ((obs = *obsp++) != 0)
-           FOR_PROVIDES(po, ppo, obs)
-             MAPSET(&obsmap, po);
-       }
-    }
-
-  queue_init(&redoq);
-  queue_init(&disabledq);
-  goterase = 0;
-  /* disable all erase jobs (including weak "keep uninstalled" rules) */
-  for (i = solv->jobrules, r = solv->rules + i; i < solv->jobrules_end; i++, r++)
-    {
-      if (r->d < 0)    /* disabled ? */
-       continue;
-      if (r->p >= 0)   /* install job? */
-       continue;
-      queue_push(&disabledq, i);
-      solver_disablerule(solv, r);
-      goterase++;
-    }
-  
-  if (goterase)
-    {
-      enabledisablelearntrules(solv);
-      removedisabledconflicts(solv, &redoq);
-    }
-
-  /*
-   * find recommended packages
-   */
-    
-  /* if redoq.count == 0 we already found all recommended in the
-   * solver run */
-  if (1)
-    {
-      Id rec, *recp, p, pp;
-
-      /* create map of all recommened packages */
-      solv->recommends_index = -1;
-      MAPZERO(&solv->recommendsmap);
-
-      /* put all packages the solver already chose in the map */
-      if (solv->decisioncnt_weak)
-       {
-         for (i = solv->decisioncnt_weak; i < solv->decisioncnt_orphan; i++)
-           {
-             Id why;
-             why = solv->decisionq_why.elements[i];
-             if (why)
-               continue;       /* forced by unit rule */
-             p = solv->decisionq.elements[i];
-             if (p < 0)
-               continue;
-             MAPSET(&solv->recommendsmap, p);
-           }
-       }
-
-      for (i = 0; i < solv->decisionq.count; i++)
-       {
-         p = solv->decisionq.elements[i];
-         if (p < 0)
-           continue;
-         s = pool->solvables + p;
-         if (s->recommends)
-           {
-             recp = s->repo->idarraydata + s->recommends;
-             while ((rec = *recp++) != 0)
-               {
-                 FOR_PROVIDES(p, pp, rec)
-                   if (solv->decisionmap[p] > 0)
-                     break;
-                 if (p)
-                   {
-                     if (!solv->dontshowinstalledrecommended)
-                       {
-                         FOR_PROVIDES(p, pp, rec)
-                           if (solv->decisionmap[p] > 0)
-                             MAPSET(&solv->recommendsmap, p);
-                       }
-                     continue; /* p != 0: already fulfilled */
-                   }
-                 FOR_PROVIDES(p, pp, rec)
-                   MAPSET(&solv->recommendsmap, p);
-               }
-           }
-       }
-      for (i = 1; i < pool->nsolvables; i++)
-       {
-         if (solv->decisionmap[i] < 0)
-           continue;
-         if (solv->decisionmap[i] > 0 && solv->dontshowinstalledrecommended)
-           continue;
-          if (MAPTST(&obsmap, i))
-           continue;
-         s = pool->solvables + i;
-         if (!MAPTST(&solv->recommendsmap, i))
-           {
-             if (!s->supplements)
-               continue;
-             if (!pool_installable(pool, s))
-               continue;
-             if (!solver_is_supplementing(solv, s))
-               continue;
-           }
-         queue_push(&solv->recommendations, i);
-       }
-      /* we use MODE_SUGGEST here so that repo prio is ignored */
-      policy_filter_unwanted(solv, &solv->recommendations, POLICY_MODE_SUGGEST);
-    }
-
-  /*
-   * find suggested packages
-   */
-    
-  if (1)
-    {
-      Id sug, *sugp, p, pp;
-
-      /* create map of all suggests that are still open */
-      solv->recommends_index = -1;
-      MAPZERO(&solv->suggestsmap);
-      for (i = 0; i < solv->decisionq.count; i++)
-       {
-         p = solv->decisionq.elements[i];
-         if (p < 0)
-           continue;
-         s = pool->solvables + p;
-         if (s->suggests)
-           {
-             sugp = s->repo->idarraydata + s->suggests;
-             while ((sug = *sugp++) != 0)
-               {
-                 FOR_PROVIDES(p, pp, sug)
-                   if (solv->decisionmap[p] > 0)
-                     break;
-                 if (p)
-                   {
-                     if (!solv->dontshowinstalledrecommended)
-                       {
-                         FOR_PROVIDES(p, pp, sug)
-                           if (solv->decisionmap[p] > 0)
-                             MAPSET(&solv->suggestsmap, p);
-                       }
-                     continue; /* already fulfilled */
-                   }
-                 FOR_PROVIDES(p, pp, sug)
-                   MAPSET(&solv->suggestsmap, p);
-               }
-           }
-       }
-      for (i = 1; i < pool->nsolvables; i++)
-       {
-         if (solv->decisionmap[i] < 0)
-           continue;
-         if (solv->decisionmap[i] > 0 && solv->dontshowinstalledrecommended)
-           continue;
-          if (MAPTST(&obsmap, i))
-           continue;
-         s = pool->solvables + i;
-         if (!MAPTST(&solv->suggestsmap, i))
-           {
-             if (!s->enhances)
-               continue;
-             if (!pool_installable(pool, s))
-               continue;
-             if (!solver_is_enhancing(solv, s))
-               continue;
-           }
-         queue_push(&solv->suggestions, i);
-       }
-      policy_filter_unwanted(solv, &solv->suggestions, POLICY_MODE_SUGGEST);
-    }
-
-  /* undo removedisabledconflicts */
-  if (redoq.count)
-    undo_removedisabledconflicts(solv, &redoq);
-  queue_free(&redoq);
-  
-  /* undo job rule disabling */
-  for (i = 0; i < disabledq.count; i++)
-    solver_enablerule(solv, solv->rules + disabledq.elements[i]);
-  queue_free(&disabledq);
-  map_free(&obsmap);
-}
-
 void
 solver_calculate_noobsmap(Pool *pool, Queue *job, Map *noobsmap)
 {
@@ -2603,7 +2389,7 @@ solver_solve(Solver *solv, Queue *job)
   POOL_DEBUG(SOLV_DEBUG_STATS, "allowuninstall=%d, allowdowngrade=%d, allowarchchange=%d, allowvendorchange=%d\n", solv->allowuninstall, solv->allowdowngrade, solv->allowarchchange, solv->allowvendorchange);
   POOL_DEBUG(SOLV_DEBUG_STATS, "promoteepoch=%d, allowselfconflicts=%d\n", pool->promoteepoch, pool->allowselfconflicts);
   POOL_DEBUG(SOLV_DEBUG_STATS, "obsoleteusesprovides=%d, implicitobsoleteusesprovides=%d, obsoleteusescolors=%d\n", pool->obsoleteusesprovides, pool->implicitobsoleteusesprovides, pool->obsoleteusescolors);
-  POOL_DEBUG(SOLV_DEBUG_STATS, "dontinstallrecommended=%d, ignorealreadyrecommended=%d, dontshowinstalledrecommended=%d\n", solv->dontinstallrecommended, solv->ignorealreadyrecommended, solv->dontshowinstalledrecommended);
+  POOL_DEBUG(SOLV_DEBUG_STATS, "dontinstallrecommended=%d, ignorealreadyrecommended=%d\n", solv->dontinstallrecommended, solv->ignorealreadyrecommended);
 
   /* create whatprovides if not already there */
   if (!pool->whatprovides)
@@ -3079,11 +2865,6 @@ solver_solve(Solver *solv, Queue *job)
   POOL_DEBUG(SOLV_DEBUG_STATS, "solver took %d ms\n", solv_timems(now));
 
   /*
-   * calculate recommended/suggested packages
-   */
-  solver_findrecommendedsuggested(solv);
-
-  /*
    * prepare solution queue if there were problems
    */
   solver_prepare_solutions(solv);
@@ -3101,6 +2882,224 @@ solver_create_transaction(Solver *solv)
   return transaction_create_decisionq(solv->pool, &solv->decisionq, &solv->noobsoletes);
 }
 
+void solver_get_orphaned(Solver *solv, Queue *orphanedq)
+{
+  queue_free(orphanedq);
+  queue_init_clone(orphanedq, &solv->orphaned);
+}
+
+void solver_get_recommendations(Solver *solv, Queue *recommendationsq, Queue *suggestionsq, int noselected)
+{
+  Pool *pool = solv->pool;
+  Queue redoq, disabledq;
+  int goterase, i;
+  Solvable *s;
+  Rule *r;
+  Map obsmap;
+
+  if (!recommendationsq && !suggestionsq)
+    return;
+
+  map_init(&obsmap, pool->nsolvables);
+  if (solv->installed)
+    {
+      Id obs, *obsp, p, po, ppo;
+      for (p = solv->installed->start; p < solv->installed->end; p++)
+       {
+         s = pool->solvables + p;
+         if (s->repo != solv->installed || !s->obsoletes)
+           continue;
+         if (solv->decisionmap[p] <= 0)
+           continue;
+         if (solv->noobsoletes.size && MAPTST(&solv->noobsoletes, p))
+           continue;
+         obsp = s->repo->idarraydata + s->obsoletes;
+         /* foreach obsoletes */
+         while ((obs = *obsp++) != 0)
+           FOR_PROVIDES(po, ppo, obs)
+             MAPSET(&obsmap, po);
+       }
+    }
+
+  queue_init(&redoq);
+  queue_init(&disabledq);
+  goterase = 0;
+  /* disable all erase jobs (including weak "keep uninstalled" rules) */
+  for (i = solv->jobrules, r = solv->rules + i; i < solv->jobrules_end; i++, r++)
+    {
+      if (r->d < 0)    /* disabled ? */
+       continue;
+      if (r->p >= 0)   /* install job? */
+       continue;
+      queue_push(&disabledq, i);
+      solver_disablerule(solv, r);
+      goterase++;
+    }
+  
+  if (goterase)
+    {
+      enabledisablelearntrules(solv);
+      removedisabledconflicts(solv, &redoq);
+    }
+
+  /*
+   * find recommended packages
+   */
+  if (recommendationsq)
+    {
+      Id rec, *recp, p, pp;
+
+      queue_empty(recommendationsq);
+      /* create map of all recommened packages */
+      solv->recommends_index = -1;
+      MAPZERO(&solv->recommendsmap);
+
+      /* put all packages the solver already chose in the map */
+      if (solv->decisioncnt_weak)
+       {
+         for (i = solv->decisioncnt_weak; i < solv->decisioncnt_orphan; i++)
+           {
+             Id why;
+             why = solv->decisionq_why.elements[i];
+             if (why)
+               continue;       /* forced by unit rule */
+             p = solv->decisionq.elements[i];
+             if (p < 0)
+               continue;
+             MAPSET(&solv->recommendsmap, p);
+           }
+       }
+
+      for (i = 0; i < solv->decisionq.count; i++)
+       {
+         p = solv->decisionq.elements[i];
+         if (p < 0)
+           continue;
+         s = pool->solvables + p;
+         if (s->recommends)
+           {
+             recp = s->repo->idarraydata + s->recommends;
+             while ((rec = *recp++) != 0)
+               {
+                 FOR_PROVIDES(p, pp, rec)
+                   if (solv->decisionmap[p] > 0)
+                     break;
+                 if (p)
+                   {
+                     if (!noselected)
+                       {
+                         FOR_PROVIDES(p, pp, rec)
+                           if (solv->decisionmap[p] > 0)
+                             MAPSET(&solv->recommendsmap, p);
+                       }
+                     continue; /* p != 0: already fulfilled */
+                   }
+                 FOR_PROVIDES(p, pp, rec)
+                   MAPSET(&solv->recommendsmap, p);
+               }
+           }
+       }
+      for (i = 1; i < pool->nsolvables; i++)
+       {
+         if (solv->decisionmap[i] < 0)
+           continue;
+         if (solv->decisionmap[i] > 0 && noselected)
+           continue;
+          if (MAPTST(&obsmap, i))
+           continue;
+         s = pool->solvables + i;
+         if (!MAPTST(&solv->recommendsmap, i))
+           {
+             if (!s->supplements)
+               continue;
+             if (!pool_installable(pool, s))
+               continue;
+             if (!solver_is_supplementing(solv, s))
+               continue;
+           }
+         queue_push(recommendationsq, i);
+       }
+      /* we use MODE_SUGGEST here so that repo prio is ignored */
+      policy_filter_unwanted(solv, recommendationsq, POLICY_MODE_SUGGEST);
+    }
+
+  /*
+   * find suggested packages
+   */
+    
+  if (suggestionsq)
+    {
+      Id sug, *sugp, p, pp;
+
+      queue_empty(suggestionsq);
+      /* create map of all suggests that are still open */
+      solv->recommends_index = -1;
+      MAPZERO(&solv->suggestsmap);
+      for (i = 0; i < solv->decisionq.count; i++)
+       {
+         p = solv->decisionq.elements[i];
+         if (p < 0)
+           continue;
+         s = pool->solvables + p;
+         if (s->suggests)
+           {
+             sugp = s->repo->idarraydata + s->suggests;
+             while ((sug = *sugp++) != 0)
+               {
+                 FOR_PROVIDES(p, pp, sug)
+                   if (solv->decisionmap[p] > 0)
+                     break;
+                 if (p)
+                   {
+                     if (!noselected)
+                       {
+                         FOR_PROVIDES(p, pp, sug)
+                           if (solv->decisionmap[p] > 0)
+                             MAPSET(&solv->suggestsmap, p);
+                       }
+                     continue; /* already fulfilled */
+                   }
+                 FOR_PROVIDES(p, pp, sug)
+                   MAPSET(&solv->suggestsmap, p);
+               }
+           }
+       }
+      for (i = 1; i < pool->nsolvables; i++)
+       {
+         if (solv->decisionmap[i] < 0)
+           continue;
+         if (solv->decisionmap[i] > 0 && noselected)
+           continue;
+          if (MAPTST(&obsmap, i))
+           continue;
+         s = pool->solvables + i;
+         if (!MAPTST(&solv->suggestsmap, i))
+           {
+             if (!s->enhances)
+               continue;
+             if (!pool_installable(pool, s))
+               continue;
+             if (!solver_is_enhancing(solv, s))
+               continue;
+           }
+         queue_push(suggestionsq, i);
+       }
+      policy_filter_unwanted(solv, suggestionsq, POLICY_MODE_SUGGEST);
+    }
+
+  /* undo removedisabledconflicts */
+  if (redoq.count)
+    undo_removedisabledconflicts(solv, &redoq);
+  queue_free(&redoq);
+  
+  /* undo job rule disabling */
+  for (i = 0; i < disabledq.count; i++)
+    solver_enablerule(solv, solv->rules + disabledq.elements[i]);
+  queue_free(&disabledq);
+  map_free(&obsmap);
+}
+
+
 /***********************************************************************/
 /* disk usage computations */
 
index 70beff7..dd1c8a7 100644 (file)
@@ -165,9 +165,7 @@ struct _Solver {
   Queue problems;                       /* list of lists of conflicting rules, < 0 for job rules */
   Queue solutions;                     /* refined problem storage space */
 
-  Queue recommendations;               /* recommended packages */
-  Queue suggestions;                   /* suggested packages */
-  Queue orphaned;                      /* orphaned packages */
+  Queue orphaned;                      /* orphaned packages (to be removed?) */
 
   int stats_learned;                   /* statistic */
   int stats_unsolvable;                        /* statistic */
@@ -293,6 +291,10 @@ extern int  solver_get_decisionlevel(Solver *solv, Id p);
 extern void solver_get_decisionqueue(Solver *solv, Queue *decisionq);
 extern int  solver_get_lastdecisionblocklevel(Solver *solv);
 extern void solver_get_decisionblock(Solver *solv, int level, Queue *decisionq);
+
+extern void solver_get_orphaned(Solver *solv, Queue *orphanedq);
+extern void solver_get_recommendations(Solver *solv, Queue *recommendationsq, Queue *suggestionsq, int noselected);
+
 extern int  solver_describe_decision(Solver *solv, Id p, Id *infop);
 extern void solver_describe_weakdep_decision(Solver *solv, Id p, Queue *whyq);
 
index 099b39e..a33e7ad 100644 (file)
@@ -302,6 +302,9 @@ solver_printdecisions(Solver *solv)
   int i, j;
   Solvable *s;
   Queue iq;
+  Queue recommendations;
+  Queue suggestions;
+  Queue orphaned;
 
   POOL_DEBUG(SOLV_DEBUG_RESULT, "\n");
   POOL_DEBUG(SOLV_DEBUG_RESULT, "transaction:\n");
@@ -373,13 +376,17 @@ solver_printdecisions(Solver *solv)
 
   POOL_DEBUG(SOLV_DEBUG_RESULT, "\n");
 
-  if (solv->recommendations.count)
+  queue_init(&recommendations);
+  queue_init(&suggestions);
+  queue_init(&orphaned);
+  solver_get_recommendations(solv, &recommendations, &suggestions, 0);
+  if (recommendations.count)
     {
       POOL_DEBUG(SOLV_DEBUG_RESULT, "recommended packages:\n");
-      for (i = 0; i < solv->recommendations.count; i++)
+      for (i = 0; i < recommendations.count; i++)
        {
-         s = pool->solvables + solv->recommendations.elements[i];
-          if (solv->decisionmap[solv->recommendations.elements[i]] > 0)
+         s = pool->solvables + recommendations.elements[i];
+          if (solv->decisionmap[recommendations.elements[i]] > 0)
            {
              if (installed && s->repo == installed)
                POOL_DEBUG(SOLV_DEBUG_RESULT, "  %s (installed)\n", pool_solvable2str(pool, s));
@@ -392,13 +399,13 @@ solver_printdecisions(Solver *solv)
       POOL_DEBUG(SOLV_DEBUG_RESULT, "\n");
     }
 
-  if (solv->suggestions.count)
+  if (suggestions.count)
     {
       POOL_DEBUG(SOLV_DEBUG_RESULT, "suggested packages:\n");
-      for (i = 0; i < solv->suggestions.count; i++)
+      for (i = 0; i < suggestions.count; i++)
        {
-         s = pool->solvables + solv->suggestions.elements[i];
-          if (solv->decisionmap[solv->suggestions.elements[i]] > 0)
+         s = pool->solvables + suggestions.elements[i];
+          if (solv->decisionmap[suggestions.elements[i]] > 0)
            {
              if (installed && s->repo == installed)
                POOL_DEBUG(SOLV_DEBUG_RESULT, "  %s (installed)\n", pool_solvable2str(pool, s));
@@ -410,12 +417,12 @@ solver_printdecisions(Solver *solv)
        }
       POOL_DEBUG(SOLV_DEBUG_RESULT, "\n");
     }
-  if (solv->orphaned.count)
+  if (orphaned.count)
     {
       POOL_DEBUG(SOLV_DEBUG_RESULT, "orphaned packages:\n");
-      for (i = 0; i < solv->orphaned.count; i++)
+      for (i = 0; i < orphaned.count; i++)
        {
-         s = pool->solvables + solv->orphaned.elements[i];
+         s = pool->solvables + orphaned.elements[i];
           if (solv->decisionmap[solv->orphaned.elements[i]] > 0)
            POOL_DEBUG(SOLV_DEBUG_RESULT, "  %s (kept)\n", pool_solvable2str(pool, s));
          else
@@ -423,6 +430,9 @@ solver_printdecisions(Solver *solv)
        }
       POOL_DEBUG(SOLV_DEBUG_RESULT, "\n");
     }
+  queue_free(&recommendations);
+  queue_free(&suggestions);
+  queue_free(&orphaned);
   transaction_free(trans);
 }