Add setgenmetaalgo method to select the desired algorithm 11/288711/5 accepted/tizen_devbase_services accepted/tizen_devbase_tools accepted/tizen/devbase/services/20230301.063747 accepted/tizen/devbase/tools/20230301.063759 submit/trunk/20230301.114030
author“zg84.zhang” <zg84.zhang@samsung.com>
Wed, 22 Feb 2023 03:11:16 +0000 (11:11 +0800)
committer“zg84.zhang” <zg84.zhang@samsung.com>
Wed, 22 Feb 2023 05:27:02 +0000 (13:27 +0800)
https://src.fedoraproject.org/rpms/perl-BSSolv/blob/3dcce328e1068c089dcdaf105cd211033aef53dd/f/0001-Implement-genmetaalgo-1.patchhttps://src.fedoraproject.org/rpms/perl-BSSolv/blob/3dcce328e1068c089dcdaf105cd211033aef53dd/f/0001-Implement-genmetaalgo-1.patch
Change-Id: I0c2e3505993dced02485805221f0614a3ff85ddc

BSSolv.xs

index e819aa9..68814e0 100644 (file)
--- a/BSSolv.xs
+++ b/BSSolv.xs
@@ -59,6 +59,7 @@ static Id buildservice_external;
 static Id buildservice_dodurl;
 static Id expander_directdepsend;
 static Id buildservice_dodcookie;
+static int genmetaalgo;
 
 /* make sure bit n is usable */
 #define MAPEXP(m, n) ((m)->size < (((n) + 8) >> 3) ? map_grow(m, n + 256) : 0)
@@ -1371,10 +1372,10 @@ create_considered(Pool *pool, Repo *repoonly, Map *considered)
 }
 
 struct metaline {
-  char *l;
-  int lastoff;
-  int nslash;
-  int killed;
+  char *l;           /* pointer to line */
+  int lastoff;       /* line offset of last path element */
+  int nslash;        /* number of slashes */
+  int killed;        /* 1: line has been killed. 2: because of a cycle package */
 };
 
 static int metacmp(const void *ap, const void *bp)
@@ -3719,6 +3720,18 @@ depsort(HV *deps, SV *mapp, SV *cycp, ...)
            solv_free(names);
        }
 
+int
+setgenmetaalgo(int algo)
+    CODE:
+      if (algo < 0)
+          algo = 1;
+      if (algo > 1)
+          croak("BSSolv::setgenmetaalgo: unsupported algo %d\n", algo);
+      genmetaalgo = algo;
+      RETVAL = algo;
+    OUTPUT:
+      RETVAL
+
 void
 gen_meta(AV *subp, ...)
     PPCODE:
@@ -3804,7 +3817,7 @@ gen_meta(AV *subp, ...)
                  }
                if (cycle)
                  {
-                   lp->killed = 1;
+                   lp->killed = 1; /* killed because line includes a subpackage */
                    if (cycle > 1)      /* ignore self cycles */
                      queue_push(&cycles, i);
                  }
@@ -3820,9 +3833,9 @@ gen_meta(AV *subp, ...)
                char *cycledata = 0;
                int cycledatalen = 0;
 
+               /* create hash of cycle packages */
                cycledata = solv_extend(cycledata, cycledatalen, 1, 1, 255);
-               cycledata[0] = 0;
-               cycledatalen += 1;
+               cycledata[cycledatalen++] = 0;
                hm = mkmask(cycles.count);
                ht = solv_calloc(hm + 1, sizeof(*ht));
                for (i = 0; i < cycles.count; i++)
@@ -3840,18 +3853,22 @@ gen_meta(AV *subp, ...)
                          break;
                        h = HASHCHAIN_NEXT(h, hh, hm);
                      }
-                   if (id)
-                     continue;
-                   cycledata = solv_extend(cycledata, cycledatalen, strlen(s) + 1, 1, 255);
-                   ht[h] = cycledatalen;
-                   strcpy(cycledata + cycledatalen, s);
-                   cycledatalen += strlen(s) + 1;
+                   if (!id)
+                     {
+                       int l = strlen(s);
+                       cycledata = solv_extend(cycledata, cycledatalen, l + 1, 1, 255);
+                       ht[h] = cycledatalen;   /* point to name */
+                       strcpy(cycledata + cycledatalen, s);
+                       cycledatalen += l + 1;
+                     }
                    if (se)
                      *se = '/';
                  }
                for (i = 0, lp = lines; i < nlines; i++, lp++)
                  {
-                   if (lp->killed || !lp->nslash)
+                   if (!lp->nslash)
+                     continue;
+                   if (lp->killed && genmetaalgo == 0)
                      continue;
                    lo = strchr(lp->l + 34, '/') + 1;
                    for (s2 = lo; *s2; s2++)
@@ -3869,12 +3886,12 @@ gen_meta(AV *subp, ...)
                          *s2 = '/';
                          if (id)
                            {
-                             lp->killed = 1;
+                             lp->killed = 2;  /* killed because it containes a cycle package */
                              break;
                            }
                          lo = s2 + 1;
                        }
-                   if (lp->killed)
+                   if (lp->killed == 2)
                      continue;
                    h = strhash(lo) & hm;
                    hh = HASHCHAIN_START;
@@ -3886,13 +3903,13 @@ gen_meta(AV *subp, ...)
                      }
                    if (id)
                      {
-                       lp->killed = 1;
+                       lp->killed = 2; /* killed because it containes a cycle package */
                      }
                  }
                solv_free(ht);
                cycledata = solv_free(cycledata);
-               queue_free(&cycles);
              }
+           queue_free(&cycles);
 
            /* cycles are pruned, now sort array */
            if (nlines > 1)
@@ -3903,7 +3920,10 @@ gen_meta(AV *subp, ...)
            for (i = 0, lp = lines; i < nlines; i++, lp++)
              {
                if (lp->killed)
-                 continue;
+                 {
+               if (genmetaalgo == 0 || lp->killed != 2)
+                     continue;
+                 }
                s = lp->l;
                h = strnhash(s, 10);
                h = strhash_cont(s + lp->lastoff, h) & hm;
@@ -3915,6 +3935,13 @@ gen_meta(AV *subp, ...)
                      break;
                    h = HASHCHAIN_NEXT(h, hh, hm);
                  }
+               if (id && genmetaalgo == 1 && lp->killed == 2)
+                 {
+                   /* also kill old line of same level */
+                   struct metaline *lp2 = lines + (id - 1);
+                   if (!lp2->killed && lp2->nslash == lp->nslash)
+                     lp2->killed = 1;
+                 }
                if (id)
                  lp->killed = 1;
                else