]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Support dumping of the order edges in testcases
authorMichael Schroeder <mls@suse.de>
Thu, 3 Mar 2022 14:35:00 +0000 (15:35 +0100)
committerMichael Schroeder <mls@suse.de>
Thu, 3 Mar 2022 14:35:00 +0000 (15:35 +0100)
ext/testcase.c
ext/testcase.h
src/libsolv.ver
src/order.c
src/transaction.h

index 4262199e8c663fcc5b995cd31678512883a697aa..035cfdbd116cb8d8f84b1e706c8f3ae64d2bcfe5 100644 (file)
@@ -101,6 +101,7 @@ static struct resultflags2str {
   { TESTCASE_RESULT_JOBS,              "jobs" },
   { TESTCASE_RESULT_USERINSTALLED,     "userinstalled" },
   { TESTCASE_RESULT_ORDER,             "order" },
+  { TESTCASE_RESULT_ORDEREDGES,                "orderedges" },
   { 0, 0 }
 };
 
@@ -1453,6 +1454,31 @@ testcase_solverresult(Solver *solv, int resultflags)
        }
       transaction_free(trans);
     }
+  if ((resultflags & TESTCASE_RESULT_ORDEREDGES) != 0)
+    {
+      Queue q;
+      int i, j;
+      Id p, p2;
+      Transaction *trans = solver_create_transaction(solv);
+      transaction_order(trans, SOLVER_TRANSACTION_KEEP_ORDEREDGES);
+      queue_init(&q);
+      for (i = 0; i < trans->steps.count; i++)
+       {
+         p = trans->steps.elements[i];
+         transaction_order_get_edges(trans, p, &q, 1);
+         for (j = 0; j < q.count; j += 2)
+           {
+             char typebuf[32], *s;
+             p2 = q.elements[j];
+             sprintf(typebuf, " -%x-> ", q.elements[j + 1]);
+             s = pool_tmpjoin(pool, "orderedge ", testcase_solvid2str(pool, p), typebuf);
+             s = pool_tmpappend(pool, s, testcase_solvid2str(pool, p2), 0);
+             strqueue_push(&sq, s);
+           }
+       }
+      queue_free(&q);
+      transaction_free(trans);
+    }
   if ((resultflags & TESTCASE_RESULT_ALTERNATIVES) != 0)
     {
       char *altprefix;
index c69098dda5be3a88bff3961b444ecd970ab62e6d..d57f116c7cb401ad70c9223f5a42210071339212 100644 (file)
@@ -22,6 +22,7 @@
 #define TESTCASE_RESULT_JOBS           (1 << 10)
 #define TESTCASE_RESULT_USERINSTALLED  (1 << 11)
 #define TESTCASE_RESULT_ORDER          (1 << 12)
+#define TESTCASE_RESULT_ORDEREDGES     (1 << 13)
 
 /* reuse solver hack, testsolv use only */
 #define TESTCASE_RESULT_REUSE_SOLVER   (1 << 31)
index 51819fbb153cdaddd4875021e99c079f9adc2423..c77f8d372d5839afae35d22fad3c04d767417235 100644 (file)
@@ -434,6 +434,7 @@ SOLV_1.0 {
                transaction_order_add_choices;
                transaction_order_get_cycle;
                transaction_order_get_cycleids;
+               transaction_order_get_edges;
                transaction_print;
                transaction_type;
        local:
index 0048376d9865b758fe3dbd91b8358b3280c287c9..f36e44683226bfeccee27c65a2ace940170f57b4 100644 (file)
@@ -35,6 +35,7 @@ struct s_TransactionOrderdata {
   Id *invedgedata;
   int ninvedgedata;
   Queue *cycles;
+  Queue *edgedataq;            /* from SOLVER_TRANSACTION_KEEP_ORDEREDGES */
 };
 
 #define TYPE_BROKEN    (1<<0)
@@ -73,6 +74,11 @@ transaction_clone_orderdata(Transaction *trans, Transaction *srctrans)
       trans->orderdata->cycles = solv_calloc(1, sizeof(Queue));
       queue_init_clone(trans->orderdata->cycles, od->cycles);
     }
+  if (od->edgedataq)
+    {
+      trans->orderdata->edgedataq = solv_calloc(1, sizeof(Queue));
+      queue_init_clone(trans->orderdata->edgedataq, od->edgedataq);
+    }
 }
 
 void
@@ -88,6 +94,11 @@ transaction_free_orderdata(Transaction *trans)
          queue_free(od->cycles);
          od->cycles = solv_free(od->cycles);
        }
+      if (od->edgedataq)
+       {
+         queue_init(od->edgedataq);
+         od->edgedataq = solv_free(od->edgedataq);
+       }
       trans->orderdata = solv_free(trans->orderdata);
     }
 }
@@ -103,6 +114,7 @@ struct orderdata {
   Queue cycles;
   Queue cyclesdata;
   int ncycles;
+  Queue edgedataq;
 };
 
 static void
@@ -331,9 +343,9 @@ addsolvableedges(struct orderdata *od, Solvable *s)
                  queue_pushunique(&depq, p2);
                }
            }
-         if (provbyinst)
+         if (provbyinst && s->repo == installed)
            {
-             /* prune to harmless ->inst edges */
+             /* prune to harmless uninst->inst edges */
              for (i = j = 0; i < depq.count; i++)
                if (pool->solvables[depq.elements[i]].repo != installed)
                  depq.elements[j++] = depq.elements[i];
@@ -375,7 +387,7 @@ addsolvableedges(struct orderdata *od, Solvable *s)
              if (pool->solvables[p2].repo != installed)
                {
                  /* all elements of depq are installs, thus have different TEs */
-                 if (pool->solvables[p].repo != installed)
+                 if (s->repo != installed)
                    {
 #if 0
                      printf("add inst->inst edge (%s -> %s -> %s)\n", pool_solvid2str(pool, p), pool_dep2str(pool, req), pool_solvid2str(pool, p2));
@@ -863,12 +875,7 @@ transaction_order(Transaction *trans, int flags)
   POOL_DEBUG(SOLV_DEBUG_STATS, "ordering transaction\n");
   /* free old data if present */
   if (trans->orderdata)
-    {
-      struct s_TransactionOrderdata *od = trans->orderdata;
-      od->tes = solv_free(od->tes);
-      od->invedgedata = solv_free(od->invedgedata);
-      trans->orderdata = solv_free(trans->orderdata);
-    }
+    transaction_free_orderdata(trans);
 
   /* create a transaction element for every active component */
   numte = 0;
@@ -893,6 +900,8 @@ transaction_order(Transaction *trans, int flags)
   od.edgedata[0] = 0;
   od.nedgedata = 1;
   queue_init(&od.cycles);
+  queue_init(&od.cyclesdata);
+  queue_init(&od.edgedataq);
 
   /* initialize TEs */
   for (i = 0, te = od.tes + 1; i < tr->count; i++)
@@ -1030,6 +1039,14 @@ transaction_order(Transaction *trans, int flags)
 #if 0
   dump_tes(&od);
 #endif
+  if ((flags & SOLVER_TRANSACTION_KEEP_ORDEREDGES) != 0)
+    {
+      queue_insertn(&od.edgedataq, 0, od.nedgedata, od.edgedata);
+      queue_insertn(&od.edgedataq, 0, numte, 0);
+      for (i = 1, te = od.tes + i; i < numte; i++, te++)
+       od.edgedataq.elements[i] = te->edges + numte;
+    }
+
   /* all edges are finally set up and there are no cycles, now the easy part.
    * Create an ordered transaction */
   now = solv_timems(0);
@@ -1199,7 +1216,7 @@ printf("free %s [%d]\n", pool_solvid2str(pool, te2->p), temedianr[od.invedgedata
   POOL_DEBUG(SOLV_DEBUG_STATS, "creating new transaction took %d ms\n", solv_timems(now));
   POOL_DEBUG(SOLV_DEBUG_STATS, "transaction ordering took %d ms\n", solv_timems(start));
 
-  if ((flags & (SOLVER_TRANSACTION_KEEP_ORDERDATA | SOLVER_TRANSACTION_KEEP_ORDERCYCLES)) != 0)
+  if ((flags & (SOLVER_TRANSACTION_KEEP_ORDERDATA | SOLVER_TRANSACTION_KEEP_ORDERCYCLES | SOLVER_TRANSACTION_KEEP_ORDEREDGES)) != 0)
     {
       struct s_TransactionOrderdata *tod;
       trans->orderdata = tod = solv_calloc(1, sizeof(*trans->orderdata));
@@ -1214,7 +1231,7 @@ printf("free %s [%d]\n", pool_solvid2str(pool, te2->p), temedianr[od.invedgedata
          queue_insertn(cycles, cycles->count, od.cycles.count, od.cycles.elements);
          queue_push(cycles, od.cycles.count / 4);
        }
-      if ((flags & SOLVER_TRANSACTION_KEEP_ORDERDATA) != 0)
+      if ((flags & (SOLVER_TRANSACTION_KEEP_ORDERDATA | SOLVER_TRANSACTION_KEEP_ORDEREDGES)) != 0)
        {
          tod->tes = od.tes;
          tod->ntes = numte;
@@ -1223,10 +1240,16 @@ printf("free %s [%d]\n", pool_solvid2str(pool, te2->p), temedianr[od.invedgedata
          od.tes = 0;
          od.invedgedata = 0;
        }
+      if ((flags & SOLVER_TRANSACTION_KEEP_ORDEREDGES) != 0)
+       {
+         Queue *edgedataq = tod->edgedataq = solv_calloc(1, sizeof(Queue));
+         queue_init_clone(edgedataq, &od.edgedataq);
+       }
     }
   solv_free(od.tes);
   solv_free(od.invedgedata);
   queue_free(&od.cycles);
+  queue_free(&od.edgedataq);
   queue_free(&od.cyclesdata);
 }
 
@@ -1501,3 +1524,32 @@ transaction_order_get_cycle(Transaction *trans, Id cid, Queue *q)
   return severity;
 }
 
+void
+transaction_order_get_edges(Transaction *trans, Id p, Queue *q, int unbroken)
+{
+  struct s_TransactionOrderdata *od = trans->orderdata;
+  struct s_TransactionElement *te;
+  int i;
+  Queue *eq;
+
+  queue_empty(q);
+  if (!od || !od->edgedataq)
+    return;
+  for (i = 1, te = od->tes + i; i < od->ntes; i++, te++)
+    if (te->p == p)
+      break;
+  if (i == od->ntes)
+    return;
+  eq = od->edgedataq;
+  for (i = eq->elements[i]; eq->elements[i]; i += 2)
+    {
+      int type = eq->elements[i + 1];
+      if (unbroken)
+       {
+         type &= ~(TYPE_BROKEN | TYPE_CYCLETAIL | TYPE_CYCLEHEAD);
+         if (type == 0)
+           continue;
+       }
+      queue_push2(q, od->tes[eq->elements[i]].p, type);
+    }
+}
index 5b01354efd955a18e08a713a4aa0fce4dd9cce1c..001412d222ab0765af0f421bb9acb62c44083e89 100644 (file)
@@ -86,6 +86,7 @@ typedef struct s_Transaction {
 /* order flags */
 #define SOLVER_TRANSACTION_KEEP_ORDERDATA      (1 << 0)
 #define SOLVER_TRANSACTION_KEEP_ORDERCYCLES    (1 << 1)
+#define SOLVER_TRANSACTION_KEEP_ORDEREDGES     (1 << 2)
 
 /* cycle severities */
 #define SOLVER_ORDERCYCLE_HARMLESS             0
@@ -137,6 +138,7 @@ extern void transaction_check_order(Transaction *trans);
 /* order cycle introspection */
 extern void transaction_order_get_cycleids(Transaction *trans, Queue *q, int minseverity);
 extern int transaction_order_get_cycle(Transaction *trans, Id cid, Queue *q);
+extern void transaction_order_get_edges(Transaction *trans, Id p, Queue *q, int unbroken);
 
 extern void transaction_free_orderdata(Transaction *trans);
 extern void transaction_clone_orderdata(Transaction *trans, Transaction *srctrans);