Order by weak and reverse dependencies also

Add reversed param to add(Single)Relation() for Supplements and Enhances

Also fix generation of reversed relations. As we generate all relations for
one package (p) at once they are all the latest on the other packages. So we
don't have to search through the list of relations there. But in the current
package the relation might have been added before others.

So we can check in package q if the relation is already there - using the
proper list depending on the direction. So we can't reverse by just switching
p and q before doing that.
This commit is contained in:
Florian Festi 2016-11-25 13:31:31 +01:00
parent 61992a4b65
commit decd7e619e
1 changed files with 70 additions and 14 deletions

View File

@ -67,7 +67,8 @@ static void rpmTSIFree(tsortInfo tsi)
static inline int addSingleRelation(rpmte p,
rpmte q,
rpmsenseFlags dsflags)
rpmsenseFlags dsflags,
int reversed)
{
struct tsortInfo_s *tsi_p, *tsi_q;
relation rel;
@ -80,9 +81,7 @@ static inline int addSingleRelation(rpmte p,
/* Erasures are reversed installs. */
if (teType == TR_REMOVED) {
rpmte r = p;
p = q;
q = r;
reversed = ! reversed;
flags = isErasePreReq(dsflags);
} else {
flags = isInstallPreReq(dsflags);
@ -94,14 +93,46 @@ static inline int addSingleRelation(rpmte p,
RPMSENSE_SCRIPT_PRE : RPMSENSE_SCRIPT_PREUN;
}
tsi_p = rpmteTSI(p);
tsi_q = rpmteTSI(q);
/* if relation got already added just update the flags */
if (tsi_q->tsi_relations && tsi_q->tsi_relations->rel_suc == tsi_p) {
if (!reversed &&
tsi_q->tsi_relations && tsi_q->tsi_relations->rel_suc == tsi_p) {
/* must be latest one added to q as we add all rels to p at once */
tsi_q->tsi_relations->rel_flags |= flags;
tsi_p->tsi_forward_relations->rel_flags |= flags;
return 0;
/* search entry in p */
for (struct relation_s * tsi = tsi_p->tsi_forward_relations;
tsi; tsi = tsi->rel_next) {
if (tsi->rel_suc == tsi_q) {
tsi->rel_flags |= flags;
return 0;
}
}
assert(0);
}
/* if relation got already added just update the flags */
if (reversed && tsi_q->tsi_forward_relations &&
tsi_q->tsi_forward_relations->rel_suc == tsi_p) {
/* must be latest one added to q as we add all rels to p at once */
tsi_q->tsi_forward_relations->rel_flags |= flags;
/* search entry in p */
for (struct relation_s * tsi = tsi_p->tsi_relations;
tsi; tsi = tsi->rel_next) {
if (tsi->rel_suc == tsi_q) {
tsi->rel_flags |= flags;
return 0;
}
}
assert(0);
}
if (reversed) {
rpmte r = p;
p = q;
q = r;
}
/* Record next "q <- p" relation (i.e. "p" requires "q"). */
@ -142,7 +173,8 @@ static inline int addSingleRelation(rpmte p,
static inline int addRelation(rpmts ts,
rpmal al,
rpmte p,
rpmds requires)
rpmds requires,
int reversed)
{
rpmte q;
rpmsenseFlags dsflags;
@ -158,18 +190,18 @@ static inline int addRelation(rpmts ts,
rpmrichOp op;
if (rpmdsParseRichDep(requires, &ds1, &ds2, &op, NULL) == RPMRC_OK) {
if (op != RPMRICHOP_ELSE)
addRelation(ts, al, p, ds1);
addRelation(ts, al, p, ds1, reversed);
if (op == RPMRICHOP_IF) {
rpmds ds21, ds22;
rpmrichOp op2;
if (rpmdsParseRichDep(requires, &ds21, &ds22, &op2, NULL) == RPMRC_OK && op2 == RPMRICHOP_ELSE) {
addRelation(ts, al, p, ds22);
addRelation(ts, al, p, ds22, reversed);
}
ds21 = rpmdsFree(ds21);
ds22 = rpmdsFree(ds22);
}
if (op == RPMRICHOP_AND || op == RPMRICHOP_OR)
addRelation(ts, al, p, ds2);
addRelation(ts, al, p, ds2, reversed);
ds1 = rpmdsFree(ds1);
ds2 = rpmdsFree(ds2);
}
@ -181,7 +213,7 @@ static inline int addRelation(rpmts ts,
if (q == NULL || q == p)
return 0;
addSingleRelation(p, q, dsflags);
addSingleRelation(p, q, dsflags, reversed);
return 0;
}
@ -559,16 +591,40 @@ int rpmtsOrder(rpmts ts)
rpmal al = (rpmteType(p) == TR_REMOVED) ?
erasedPackages : tsmem->addedPackages;
rpmds requires = rpmdsInit(rpmteDS(p, RPMTAG_REQUIRENAME));
rpmds recommends = rpmdsInit(rpmteDS(p, RPMTAG_RECOMMENDNAME));
rpmds suggests = rpmdsInit(rpmteDS(p, RPMTAG_SUGGESTNAME));
rpmds supplements = rpmdsInit(rpmteDS(p, RPMTAG_SUPPLEMENTNAME));
rpmds enhances = rpmdsInit(rpmteDS(p, RPMTAG_ENHANCENAME));
rpmds order = rpmdsInit(rpmteDS(p, RPMTAG_ORDERNAME));
while (rpmdsNext(requires) >= 0) {
/* Record next "q <- p" relation (i.e. "p" requires "q"). */
(void) addRelation(ts, al, p, requires);
(void) addRelation(ts, al, p, requires, 0);
}
while (rpmdsNext(recommends) >= 0) {
/* Record next "q <- p" relation (i.e. "p" recommends "q"). */
(void) addRelation(ts, al, p, recommends, 0);
}
while (rpmdsNext(suggests) >= 0) {
/* Record next "q <- p" relation (i.e. "p" suggests "q"). */
(void) addRelation(ts, al, p, suggests, 0);
}
while (rpmdsNext(order) >= 0) {
/* Record next "q <- p" ordering request */
(void) addRelation(ts, al, p, order);
(void) addRelation(ts, al, p, order, 0);
}
while (rpmdsNext(supplements) >= 0) {
/* Record next "p -> q" relation (i.e. "q" supplemented by "p"). */
(void) addRelation(ts, al, p, suggests, 1);
}
while (rpmdsNext(enhances) >= 0) {
/* Record next "p <- q" relation (i.e. "q" is enhanced by "p"). */
(void) addRelation(ts, al, p, suggests, 1);
}
}