diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2010-10-25 15:03:56 +0300 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2010-10-25 15:40:24 +0300 |
commit | 0d4b7b8f3a0a2f0de7a30fd51c86be6849e54329 (patch) | |
tree | 5a93b560323142dbc8134b937a72763a9c7d1410 /lib/order.c | |
parent | 6281e4a215313f74244a6e3b027061d64d65895e (diff) | |
download | librpm-tizen-0d4b7b8f3a0a2f0de7a30fd51c86be6849e54329.tar.gz librpm-tizen-0d4b7b8f3a0a2f0de7a30fd51c86be6849e54329.tar.bz2 librpm-tizen-0d4b7b8f3a0a2f0de7a30fd51c86be6849e54329.zip |
Create less draconian loops for grouped collections
- Instead of creating a completely unresolvable tangle of pre-requisites
between all collection members and their requirements, just add
a single relation loop of all the packages in a (grouped) collection,
effectively turning it into a strongly connected component. The
loop-cutting algorithm has slightly better chances of surviving this
while still enforcing the collection members to be installed in one
lump. Also only process each collection just once.
Diffstat (limited to 'lib/order.c')
-rw-r--r-- | lib/order.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/lib/order.c b/lib/order.c index e5b1c3efd..e794725aa 100644 --- a/lib/order.c +++ b/lib/order.c @@ -224,7 +224,6 @@ static inline int addRelation(rpmts ts, rpmds requires) { rpmte q; - ARGV_const_t qcolls; rpmsenseFlags dsflags; dsflags = rpmdsFlags(requires); @@ -245,19 +244,38 @@ static inline int addRelation(rpmts ts, addSingleRelation(p, q, dsflags); - /* If q is a member of any grouped collections, make sure p requires - * all packages that are also in those collections */ - for (qcolls = rpmteCollections(q); qcolls && *qcolls; qcolls++) { + return 0; +} + +/* + * Collections might have special ordering requirements. Notably + * sepolicy collection requires having all the bits in the collection + * close to each other. We try to ensure this by creating a strongly + * connected component of such "grouped" collections, by introducing + * an artificial relation loop across the all its members. + */ +static int addCollRelations(rpmal al, rpmte p, ARGV_t *seenColls) +{ + ARGV_const_t qcolls; + + for (qcolls = rpmteCollections(p); qcolls && *qcolls; qcolls++) { char * flags; + if (argvSearch(*seenColls, *qcolls, NULL)) + continue; + flags = rstrscat(NULL, "%{__collection_", *qcolls, "_flags}", NULL); if (rpmExpandNumeric(flags) & 0x1) { rpmte *tes = rpmalAllInCollection(al, *qcolls); for (rpmte *te = tes; te && *te; te++) { - addSingleRelation(p, *te, RPMSENSE_SCRIPT_PRE); + rpmte next = (*(te + 1) != NULL) ? *(te + 1) : *tes; + addSingleRelation(*te, next, RPMSENSE_ANY); } _free(tes); } free(flags); + + argvAdd(seenColls, *qcolls); + argvSort(*seenColls, NULL); } return 0; @@ -606,6 +624,7 @@ int rpmtsOrder(rpmts ts) scc SCCs; int nelem = rpmtsNElements(ts); tsortInfo sortInfo = xcalloc(nelem, sizeof(struct tsortInfo_s)); + ARGV_t seenColls = NULL; (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_ORDER), 0); @@ -633,7 +652,11 @@ int rpmtsOrder(rpmts ts) /* Record next "q <- p" relation (i.e. "p" requires "q"). */ (void) addRelation(ts, al, p, requires); } + + addCollRelations(al, p, &seenColls); } + + seenColls = argvFree(seenColls); pi = rpmtsiFree(pi); newOrder = xcalloc(tsmem->orderCount, sizeof(*newOrder)); |