Filter out duplicate problems when adding to element problem sets
authorPanu Matilainen <pmatilai@redhat.com>
Fri, 26 Mar 2010 10:23:47 +0000 (12:23 +0200)
committerPanu Matilainen <pmatilai@redhat.com>
Fri, 26 Mar 2010 10:47:18 +0000 (12:47 +0200)
- Problems associated with a transaction element are necessarily unique
  to that element, so when filtered there we don't have to worry about
  skipping dupes elsewhere like in merged sets. This can actually lead
  to apparent duplicates in the current problem report output (eg in cases
  where multiple packages provide the same dependency which would be
  removed, like multilib packages), but this is only an artifact of
  they way the problems are currently printed out.
- While this is still a dumb linear search, it can be several seconds
  faster than the previous filtering in rpmpsPrint(), which is now
  just a dumb convenience function.

lib/rpmps.c
lib/rpmte.c

index bdc2ba4..7f089af 100644 (file)
@@ -194,35 +194,15 @@ int rpmpsMerge(rpmps dest, rpmps src)
 
 void rpmpsPrint(FILE *fp, rpmps ps)
 {
-    char * msg = NULL;
-    rpmpsi psi = NULL;
-    int i;
-
-    if (ps == NULL || ps->probs == NULL || ps->numProblems <= 0)
-       return;
-
-    if (fp == NULL)
-       fp = stderr;
-
-    psi = rpmpsInitIterator(ps);
-    while ((i = rpmpsNextIterator(psi)) >= 0) {
-       int j;
-       rpmProblem p = rpmpsGetProblem(psi);
-
-       rpmpsi psif = rpmpsInitIterator(ps);
-       /* Filter already displayed problems. */
-       while ((j = rpmpsNextIterator(psif)) < i) {
-           if (rpmProblemCompare(p, rpmpsGetProblem(psif)) == 0)
-               break;
-       }
-       rpmpsFreeIterator(psif);
-       if (j < i)
-           continue;
-
-       msg = rpmProblemString(p);
-       fprintf(fp, "\t%s\n", msg);
-       msg = _free(msg);
-
+    rpmProblem p;
+    rpmpsi psi = rpmpsInitIterator(ps);
+    FILE *f = (fp != NULL) ? fp : stderr;
+
+    while ((p = rpmpsiNext(psi))) {
+       char *msg = rpmProblemString(p);
+       fprintf(f, "\t%s\n", msg);
+       free(msg);
     }
-    psi = rpmpsFreeIterator(psi);
+    rpmpsFreeIterator(psi);
 }
+
index cf46236..10e9bee 100644 (file)
@@ -721,11 +721,22 @@ static void appendProblem(rpmte te, rpmProblemType type,
                const char * pkgNEVR, fnpyKey key, const char * altNEVR,
                const char * str, uint64_t number)
 {
-    if (te->probs == NULL)
-       te->probs = rpmpsCreate();
-
+    rpmProblem o;
     rpmProblem p = rpmProblemCreate(type, pkgNEVR, key, altNEVR, str, number);
-    rpmpsAppendProblem(te->probs, p);
+    rpmpsi psi = rpmpsInitIterator(te->probs);
+
+    /* Only add new, unique problems to the set */
+    while ((o = rpmpsiNext(psi))) {
+       if (rpmProblemCompare(p, o) == 0)
+           break;
+    }
+    rpmpsFreeIterator(psi);
+
+    if (o == NULL) {
+       if (te->probs == NULL)
+           te->probs = rpmpsCreate();
+       rpmpsAppendProblem(te->probs, p);
+    }
     rpmProblemFree(p);
 }