Imported Upstream version 0.7.16
[platform/upstream/libsolv.git] / src / solver.c
index 5453b39..9c02cc7 100644 (file)
@@ -1198,7 +1198,7 @@ createbranch(Solver *solv, int level, Queue *dq, Id p, Id data)
   int i;
   IF_POOLDEBUG (SOLV_DEBUG_POLICY)
     {
-      POOL_DEBUG (SOLV_DEBUG_POLICY, "creating a branch:\n");
+      POOL_DEBUG (SOLV_DEBUG_POLICY, "creating a branch [data=%d]:\n", data);
       for (i = 0; i < dq->count; i++)
        POOL_DEBUG (SOLV_DEBUG_POLICY, "  - %s\n", pool_solvid2str(pool, dq->elements[i]));
     }
@@ -1218,7 +1218,7 @@ takebranch(Solver *solv, int pos, int end, const char *msg, int disablerules)
 #if 0
   {
     int i;
-    printf("branch group level %d [%d-%d] %d %d:\n", solv->branches.elements[end - 1], start, end, solv->branches.elements[end - 4], solv->branches.elements[end - 3]);
+    printf("branch group level %d [%d-%d] %d %d:\n", solv->branches.elements[end - 1], end - solv->branches.elements[end - 2], end, solv->branches.elements[end - 4], solv->branches.elements[end - 3]);
     for (i = end - solv->branches.elements[end - 2]; i < end - 4; i++)
       printf("%c %c%s\n", i == pos ? 'x' : ' ', solv->branches.elements[i] >= 0 ? ' ' : '-', pool_solvid2str(pool, solv->branches.elements[i] >= 0 ? solv->branches.elements[i] : -solv->branches.elements[i]));
   }
@@ -1910,6 +1910,8 @@ resolve_dependencies(Solver *solv, int level, int disablerules, Queue *dq)
   Rule *r;
   int origlevel = level;
   Id p, *dp;
+  int focusbest = solv->focus_best && solv->do_extra_reordering;
+  Repo *installed = solv->installed;
 
   /*
    * decide
@@ -1928,7 +1930,7 @@ resolve_dependencies(Solver *solv, int level, int disablerules, Queue *dq)
        }
       if (i == solv->nrules)
        i = 1;
-      if (solv->focus_best && solv->do_extra_reordering && i >= solv->featurerules)
+      if (focusbest && i >= solv->featurerules)
        continue;
       r = solv->rules + i;
       if (r->d < 0)            /* ignore disabled rules */
@@ -1938,6 +1940,19 @@ resolve_dependencies(Solver *solv, int level, int disablerules, Queue *dq)
          if (r->d == 0 || solv->decisionmap[-r->p] <= 0)
            continue;
        }
+      if (focusbest && r->d != 0 && installed)
+       {
+         /* make sure at least one negative literal is from a new package */
+         if (!(r->p < 0 && pool->solvables[-r->p].repo != installed))
+           {
+             dp = pool->whatprovidesdata + r->d;
+             while ((p = *dp++) != 0)
+               if (p < 0 && solv->decisionmap[-p] > 0 && pool->solvables[-p].repo != installed)
+                 break;
+             if (!p)
+               continue;               /* sorry */
+           }
+       }
       if (dq->count)
        queue_empty(dq);
       if (r->d == 0)
@@ -2074,6 +2089,8 @@ add_complex_recommends(Solver *solv, Id rec, Queue *dq, Map *dqmap)
              queue_truncate(dq, blkcnt);
              break;
            }
+         if (solv->decisionmap[p] < 0)
+           continue;
          if (dqmap)
            {
              if (!MAPTST(dqmap, p))
@@ -2081,8 +2098,6 @@ add_complex_recommends(Solver *solv, Id rec, Queue *dq, Map *dqmap)
            }
          else
            {
-             if (solv->decisionmap[p] < 0)
-               continue;
              if (solv->process_orphans && solv->installed && pool->solvables[p].repo == solv->installed && (solv->droporphanedmap_all || (solv->droporphanedmap.size && MAPTST(&solv->droporphanedmap, p - solv->installed->start))))
                continue;
            }
@@ -3091,6 +3106,12 @@ add_update_target(Solver *solv, Id p, Id how)
   if (s->repo == installed)
     {
       queue_push2(solv->update_targets, p, p);
+      FOR_PROVIDES(pi, pip, s->name)
+       {
+         Solvable *si = pool->solvables + pi;
+         if (si->repo == installed && si->name == s->name && pi != p)
+           queue_push2(solv->update_targets, pi, p);
+       }
       return;
     }
   identicalp = 0;
@@ -3219,7 +3240,7 @@ addedmap2deduceq(Solver *solv, Map *addedmap)
       p = -r->p;
       if (!MAPTST(addedmap, p))
        {
-         /* should never happen, but... */
+         /* this can happen with complex dependencies that have more than one pos literal */
          if (!solv->addedmap_deduceq.count || solv->addedmap_deduceq.elements[solv->addedmap_deduceq.count - 1] != -p)
             queue_push(&solv->addedmap_deduceq, -p);
          continue;
@@ -3259,7 +3280,7 @@ deduceq2addedmap(Solver *solv, Map *addedmap)
       if (p > 0)
        MAPSET(addedmap, p);
       else
-       MAPCLR(addedmap, p);
+       MAPCLR(addedmap, -p);
     }
 }
 
@@ -3362,6 +3383,7 @@ solver_solve(Solver *solv, Queue *job)
   int hasbestinstalljob = 0;
   int hasfavorjob = 0;
   int haslockjob = 0;
+  int hasblacklistjob = 0;
 
   solve_start = solv_timems(0);
 
@@ -3972,6 +3994,10 @@ solver_solve(Solver *solv, Queue *job)
          POOL_DEBUG(SOLV_DEBUG_JOB, "job: %s %s\n", (how & SOLVER_JOBMASK) == SOLVER_FAVOR ? "favor" : "disfavor", solver_select2str(pool, select, what));
          hasfavorjob = 1;
          break;
+       case SOLVER_BLACKLIST:
+         POOL_DEBUG(SOLV_DEBUG_JOB, "job: blacklist %s\n", solver_select2str(pool, select, what));
+         hasblacklistjob = 1;
+         break;
        default:
          POOL_DEBUG(SOLV_DEBUG_JOB, "job: unknown job\n");
          break;
@@ -4025,6 +4051,11 @@ solver_solve(Solver *solv, Queue *job)
   else
     solv->yumobsrules = solv->yumobsrules_end = solv->nrules;
 
+  if (hasblacklistjob)
+    solver_addblackrules(solv);
+  else
+    solv->blackrules = solv->blackrules_end = solv->nrules;
+
   if (solv->havedisfavored && solv->strongrecommends && solv->recommendsruleq)
     solver_addrecommendsrules(solv);
   else
@@ -4836,6 +4867,9 @@ pool_job2str(Pool *pool, Id how, Id what, Id flagmask)
     case SOLVER_DISFAVOR:
       strstart = "disfavor ";
       break;
+    case SOLVER_BLACKLIST:
+      strstart = "blacklist ";
+      break;
     default:
       strstart = "unknown job ";
       break;