optimization: check key storage before doing the forward
[platform/upstream/libsolv.git] / src / transaction.c
index 071f156..69c12d9 100644 (file)
@@ -46,6 +46,7 @@ obsq_sortcmp(const void *ap, const void *bp, void *dp)
   obs = pool->solvables + ob;
   if (oas->name != obs->name)
     {
+      /* bring "same name" obsoleters (i.e. upgraders) to front */
       if (oas->name == s->name)
         return -1;
       if (obs->name == s->name)
@@ -165,9 +166,19 @@ transaction_base_type(Transaction *trans, Id p)
     }
   else
     {
+      /* install or multiinstall */
       int multi = trans->multiversionmap.size && MAPTST(&trans->multiversionmap, p);
       if (multi)
-       return p2 ? SOLVER_TRANSACTION_MULTIREINSTALL : SOLVER_TRANSACTION_MULTIINSTALL;
+       {
+         if (p2)
+           {
+             s = pool->solvables + p;
+             s2 = pool->solvables + p2;
+             if (s->name == s2->name && s->arch == s2->arch && s->evr == s2->evr)
+               return SOLVER_TRANSACTION_MULTIREINSTALL;
+           }
+         return SOLVER_TRANSACTION_MULTIINSTALL;
+       }
       if (!p2)
        return SOLVER_TRANSACTION_INSTALL;
       s = pool->solvables + p;
@@ -188,6 +199,38 @@ transaction_base_type(Transaction *trans, Id p)
     }
 }
 
+static inline int
+is_pseudo_package(Pool *pool, Solvable *s)
+{
+  const char *n = pool_id2str(pool, s->name);
+  if (!strncmp(n, "patch:", 6))
+    return 1;
+  if (!strncmp(n, "pattern:", 8))
+    return 1;
+  return 0;
+}
+
+static int
+obsoleted_by_pseudos_only(Transaction *trans, Id p)
+{
+  Pool *pool = trans->pool;
+  Queue q;
+  Id op;
+  int i;
+
+  op = transaction_obs_pkg(trans, p);
+  if (op && !is_pseudo_package(pool, pool->solvables + op))
+    return 0;
+  queue_init(&q);
+  transaction_all_obs_pkgs(trans, p, &q);
+  for (i = 0; i < q.count; i++)
+    if (!is_pseudo_package(pool, pool->solvables + q.elements[i]))
+      break;
+  i = !q.count || i < q.count ? 0 : 1;
+  queue_free(&q);
+  return i;
+}
+
 /*
  * return type of transaction element
  *
@@ -208,14 +251,8 @@ transaction_type(Transaction *trans, Id p, int mode)
     return SOLVER_TRANSACTION_IGNORE;
 
   /* XXX: SUSE only? */
-  if (!(mode & SOLVER_TRANSACTION_KEEP_PSEUDO))
-    {
-      const char *n = pool_id2str(pool, s->name);
-      if (!strncmp(n, "patch:", 6))
-       return SOLVER_TRANSACTION_IGNORE;
-      if (!strncmp(n, "pattern:", 8))
-       return SOLVER_TRANSACTION_IGNORE;
-    }
+  if (!(mode & SOLVER_TRANSACTION_KEEP_PSEUDO) && is_pseudo_package(pool, s))
+    return SOLVER_TRANSACTION_IGNORE;
 
   type = transaction_base_type(trans, p);
 
@@ -228,7 +265,12 @@ transaction_type(Transaction *trans, Id p, int mode)
       if (type == SOLVER_TRANSACTION_ERASE || type == SOLVER_TRANSACTION_INSTALL || type == SOLVER_TRANSACTION_MULTIINSTALL)
        return type;
       if (s->repo == pool->installed)
-       return SOLVER_TRANSACTION_IGNORE;       /* ignore as we're being obsoleted */
+       {
+         /* check if we're obsoleted by pseudos only */
+         if (obsoleted_by_pseudos_only(trans, s - pool->solvables))
+           return SOLVER_TRANSACTION_ERASE;
+         return SOLVER_TRANSACTION_IGNORE;     /* ignore as we're being obsoleted */
+       }
       if (type == SOLVER_TRANSACTION_MULTIREINSTALL)
        return SOLVER_TRANSACTION_MULTIINSTALL;
       return SOLVER_TRANSACTION_INSTALL;
@@ -260,15 +302,19 @@ transaction_type(Transaction *trans, Id p, int mode)
   if (s->repo == pool->installed && (mode & SOLVER_TRANSACTION_SHOW_ACTIVE) == 0)
     {
       /* erase element and we're showing the passive side */
-      if ((mode & SOLVER_TRANSACTION_SHOW_OBSOLETES) == 0 && type == SOLVER_TRANSACTION_OBSOLETED)
+      if (type == SOLVER_TRANSACTION_OBSOLETED && (mode & SOLVER_TRANSACTION_SHOW_OBSOLETES) == 0)
        type = SOLVER_TRANSACTION_ERASE;
+      if (type == SOLVER_TRANSACTION_OBSOLETED && (mode & SOLVER_TRANSACTION_OBSOLETE_IS_UPGRADE) != 0)
+       type = SOLVER_TRANSACTION_UPGRADED;
       return type;
     }
   if (s->repo != pool->installed && (mode & SOLVER_TRANSACTION_SHOW_ACTIVE) != 0)
     {
       /* install element and we're showing the active side */
-      if ((mode & SOLVER_TRANSACTION_SHOW_OBSOLETES) == 0 && type == SOLVER_TRANSACTION_OBSOLETES)
+      if (type == SOLVER_TRANSACTION_OBSOLETES && (mode & SOLVER_TRANSACTION_SHOW_OBSOLETES) == 0)
        type = SOLVER_TRANSACTION_INSTALL;
+      if (type == SOLVER_TRANSACTION_OBSOLETES && (mode & SOLVER_TRANSACTION_OBSOLETE_IS_UPGRADE) != 0)
+       type = SOLVER_TRANSACTION_UPGRADE;
       return type;
     }
 
@@ -572,11 +618,11 @@ create_transaction_info(Transaction *trans, Queue *decisionq)
            continue;
          if (!pool->implicitobsoleteusesprovides && s->name != s2->name)
            continue;
-         if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2))
+         if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, s2))
            continue;
          queue_push2(ti, p, p2);
        }
-      if (s->obsoletes && !multi)
+      if (s->obsoletes && (!multi || !pool->noobsoletesmultiversion))
        {
          Id obs, *obsp = s->repo->idarraydata + s->obsoletes;
          while ((obs = *obsp++) != 0)
@@ -2072,7 +2118,7 @@ transaction_check_order(Transaction *trans)
   Map ins, seen;
   int i;
 
-  POOL_DEBUG(SOLV_WARN, "\nchecking transaction order...\n");
+  POOL_DEBUG(SOLV_DEBUG_RESULT, "\nchecking transaction order...\n");
   map_init(&ins, pool->nsolvables);
   map_init(&seen, pool->nsolvables);
   if (pool->installed)
@@ -2097,5 +2143,5 @@ transaction_check_order(Transaction *trans)
     }
   map_free(&seen);
   map_free(&ins);
-  POOL_DEBUG(SOLV_WARN, "transaction order check done.\n");
+  POOL_DEBUG(SOLV_DEBUG_RESULT, "transaction order check done.\n");
 }