From e9afed34930887add2c54e08141bbf4d5a98c256 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E2=80=9Czg84=2Ezhang=E2=80=9D?= Date: Wed, 22 Feb 2023 11:11:16 +0800 Subject: [PATCH] Add setgenmetaalgo method to select the desired algorithm 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 | 65 ++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/BSSolv.xs b/BSSolv.xs index e819aa9..68814e0 100644 --- 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 -- 2.7.4