X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Forder.c;h=cba977b7ec0facd921335253994ea619b37c271c;hb=9c08bb3b899936e1eb9b6ab9d0cef17501ad6bab;hp=d560865cf2bea0d68f51708188e1d96bd561f39a;hpb=70c6207bfdb27f170377015f65f22e8ba50f6a10;p=platform%2Fupstream%2Flibsolv.git diff --git a/src/order.c b/src/order.c index d560865..cba977b 100644 --- a/src/order.c +++ b/src/order.c @@ -23,14 +23,14 @@ #include "repo.h" #include "util.h" -struct _TransactionElement { +struct s_TransactionElement { Id p; /* solvable id */ Id edges; /* pointer into edges data */ Id mark; }; -struct _TransactionOrderdata { - struct _TransactionElement *tes; +struct s_TransactionOrderdata { + struct s_TransactionElement *tes; int ntes; Id *invedgedata; int ninvedgedata; @@ -43,8 +43,11 @@ struct _TransactionOrderdata { #define TYPE_REQ_P (1<<2) #define TYPE_PREREQ_P (1<<3) -#define TYPE_REQ (1<<4) -#define TYPE_PREREQ (1<<5) +#define TYPE_SUG (1<<4) +#define TYPE_REC (1<<5) + +#define TYPE_REQ (1<<6) +#define TYPE_PREREQ (1<<7) #define TYPE_CYCLETAIL (1<<16) #define TYPE_CYCLEHEAD (1<<17) @@ -54,7 +57,7 @@ struct _TransactionOrderdata { void transaction_clone_orderdata(Transaction *trans, Transaction *srctrans) { - struct _TransactionOrderdata *od = srctrans->orderdata; + struct s_TransactionOrderdata *od = srctrans->orderdata; if (!od) return; trans->orderdata = solv_calloc(1, sizeof(*trans->orderdata)); @@ -74,7 +77,7 @@ transaction_free_orderdata(Transaction *trans) { if (trans->orderdata) { - struct _TransactionOrderdata *od = trans->orderdata; + struct s_TransactionOrderdata *od = trans->orderdata; od->tes = solv_free(od->tes); od->invedgedata = solv_free(od->invedgedata); if (od->cycles) @@ -88,7 +91,7 @@ transaction_free_orderdata(Transaction *trans) struct orderdata { Transaction *trans; - struct _TransactionElement *tes; + struct s_TransactionElement *tes; int ntes; Id *edgedata; int nedgedata; @@ -99,14 +102,14 @@ struct orderdata { int ncycles; }; -static int +static void addteedge(struct orderdata *od, int from, int to, int type) { int i; - struct _TransactionElement *te; + struct s_TransactionElement *te; if (from == to) - return 0; + return; /* printf("edge %d(%s) -> %d(%s) type %x\n", from, pool_solvid2str(pool, od->tes[from].p), to, pool_solvid2str(pool, od->tes[to].p), type); */ @@ -114,13 +117,10 @@ addteedge(struct orderdata *od, int from, int to, int type) for (i = te->edges; od->edgedata[i]; i += 2) if (od->edgedata[i] == to) break; - /* test of brokenness */ - if (type == TYPE_BROKEN) - return od->edgedata[i] && (od->edgedata[i + 1] & TYPE_BROKEN) != 0 ? 1 : 0; if (od->edgedata[i]) { od->edgedata[i + 1] |= type; - return 0; + return; } if (i + 1 == od->nedgedata) { @@ -142,16 +142,15 @@ addteedge(struct orderdata *od, int from, int to, int type) od->edgedata[i + 1] = type; od->edgedata[i + 2] = 0; /* end marker */ od->nedgedata = i + 3; - return 0; } -static int +static void addedge(struct orderdata *od, Id from, Id to, int type) { Transaction *trans = od->trans; Pool *pool = trans->pool; Solvable *s; - struct _TransactionElement *te; + struct s_TransactionElement *te; int i; /* printf("addedge %d %d type %d\n", from, to, type); */ @@ -163,16 +162,15 @@ addedge(struct orderdata *od, Id from, Id to, int type) from = trans->transaction_installed[from - pool->installed->start]; else { - int ret = 0; Queue ti; Id tibuf[5]; queue_init_buffer(&ti, tibuf, sizeof(tibuf)/sizeof(*tibuf)); transaction_all_obs_pkgs(trans, from, &ti); for (i = 0; i < ti.count; i++) - ret |= addedge(od, ti.elements[i], to, type); + addedge(od, ti.elements[i], to, type); queue_free(&ti); - return ret; + return; } } s = pool->solvables + to; @@ -183,16 +181,15 @@ addedge(struct orderdata *od, Id from, Id to, int type) to = trans->transaction_installed[to - pool->installed->start]; else { - int ret = 0; Queue ti; Id tibuf[5]; queue_init_buffer(&ti, tibuf, sizeof(tibuf)/sizeof(*tibuf)); transaction_all_obs_pkgs(trans, to, &ti); for (i = 0; i < ti.count; i++) - ret |= addedge(od, from, ti.elements[i], type); + addedge(od, from, ti.elements[i], type); queue_free(&ti); - return ret; + return; } } @@ -201,16 +198,17 @@ addedge(struct orderdata *od, Id from, Id to, int type) if (te->p == to) break; if (i == od->ntes) - return 0; + return; to = i; for (i = 1, te = od->tes + i; i < od->ntes; i++, te++) if (te->p == from) break; if (i == od->ntes) - return 0; + return; + from = i; - return addteedge(od, i, to, type); + addteedge(od, from, to, type); } static inline int @@ -245,21 +243,21 @@ addsolvableedges(struct orderdata *od, Solvable *s) { Transaction *trans = od->trans; Pool *pool = trans->pool; - Id req, *reqp, con, *conp; Id p, p2, pp2; int i, j, pre, numins; Repo *installed = pool->installed; Solvable *s2; - Queue reqq; + Queue depq; int provbyinst; #if 0 printf("addsolvableedges %s\n", pool_solvable2str(pool, s)); #endif p = s - pool->solvables; - queue_init(&reqq); + queue_init(&depq); if (s->requires) { + Id req, *reqp; reqp = s->repo->idarraydata + s->requires; pre = TYPE_REQ; while ((req = *reqp++) != 0) @@ -269,15 +267,7 @@ addsolvableedges(struct orderdata *od, Solvable *s) pre = TYPE_PREREQ; continue; } -#if 0 - if (pre != TYPE_PREREQ && installed && s->repo == installed) - { - /* ignore normal requires if we're getting obsoleted */ - if (trans->transaction_installed[p - pool->installed->start]) - continue; - } -#endif - queue_empty(&reqq); + queue_empty(&depq); numins = 0; /* number of packages to be installed providing it */ provbyinst = 0; /* provided by kept package */ FOR_PROVIDES(p2, pp2, req) @@ -285,19 +275,13 @@ addsolvableedges(struct orderdata *od, Solvable *s) s2 = pool->solvables + p2; if (p2 == p) { - reqq.count = 0; /* self provides */ + depq.count = 0; /* self provides */ break; } if (s2->repo == installed && !MAPTST(&trans->transactsmap, p2)) { provbyinst = 1; -#if 0 - printf("IGNORE inst provides %s by %s\n", pool_dep2str(pool, req), pool_solvable2str(pool, s2)); - reqq.count = 0; /* provided by package that stays installed */ - break; -#else continue; -#endif } if (s2->repo != installed && !MAPTST(&trans->transactsmap, p2)) continue; /* package stays uninstalled */ @@ -305,7 +289,7 @@ addsolvableedges(struct orderdata *od, Solvable *s) if (s->repo == installed) { /* s gets uninstalled */ - queue_pushunique(&reqq, p2); + queue_pushunique(&depq, p2); if (s2->repo != installed) numins++; } @@ -313,55 +297,53 @@ addsolvableedges(struct orderdata *od, Solvable *s) { if (s2->repo == installed) continue; /* s2 gets uninstalled */ - queue_pushunique(&reqq, p2); + queue_pushunique(&depq, p2); } } if (provbyinst) { /* prune to harmless ->inst edges */ - for (i = j = 0; i < reqq.count; i++) - if (pool->solvables[reqq.elements[i]].repo != installed) - reqq.elements[j++] = reqq.elements[i]; - reqq.count = j; + for (i = j = 0; i < depq.count; i++) + if (pool->solvables[depq.elements[i]].repo != installed) + depq.elements[j++] = depq.elements[i]; + depq.count = j; } - if (numins && reqq.count) + if (numins && depq.count) { if (s->repo == installed) { - for (i = 0; i < reqq.count; i++) + for (i = 0; i < depq.count; i++) { - if (pool->solvables[reqq.elements[i]].repo == installed) + if (pool->solvables[depq.elements[i]].repo == installed) { - for (j = 0; j < reqq.count; j++) + for (j = 0; j < depq.count; j++) { - if (pool->solvables[reqq.elements[j]].repo != installed) + if (pool->solvables[depq.elements[j]].repo != installed) { - if (trans->transaction_installed[reqq.elements[i] - pool->installed->start] == reqq.elements[j]) + if (trans->transaction_installed[depq.elements[i] - pool->installed->start] == depq.elements[j]) continue; /* no self edge */ #if 0 - printf("add interrreq uninst->inst edge (%s -> %s -> %s)\n", pool_solvid2str(pool, reqq.elements[i]), pool_dep2str(pool, req), pool_solvid2str(pool, reqq.elements[j])); + printf("add interrreq uninst->inst edge (%s -> %s -> %s)\n", pool_solvid2str(pool, depq.elements[i]), pool_dep2str(pool, req), pool_solvid2str(pool, depq.elements[j])); #endif - addedge(od, reqq.elements[i], reqq.elements[j], pre == TYPE_PREREQ ? TYPE_PREREQ_P : TYPE_REQ_P); + addedge(od, depq.elements[i], depq.elements[j], pre == TYPE_PREREQ ? TYPE_PREREQ_P : TYPE_REQ_P); } } } } } /* no mixed types, remove all deps on uninstalls */ - for (i = j = 0; i < reqq.count; i++) - if (pool->solvables[reqq.elements[i]].repo != installed) - reqq.elements[j++] = reqq.elements[i]; - reqq.count = j; + for (i = j = 0; i < depq.count; i++) + if (pool->solvables[depq.elements[i]].repo != installed) + depq.elements[j++] = depq.elements[i]; + depq.count = j; } - if (!reqq.count) - continue; - for (i = 0; i < reqq.count; i++) + for (i = 0; i < depq.count; i++) { - p2 = reqq.elements[i]; + p2 = depq.elements[i]; if (pool->solvables[p2].repo != installed) { - /* all elements of reqq are installs, thus have different TEs */ + /* all elements of depq are installs, thus have different TEs */ if (pool->solvables[p].repo != installed) { #if 0 @@ -399,6 +381,7 @@ addsolvableedges(struct orderdata *od, Solvable *s) } if (s->conflicts) { + Id con, *conp; conp = s->repo->idarraydata + s->conflicts; while ((con = *conp++) != 0) { @@ -435,13 +418,83 @@ addsolvableedges(struct orderdata *od, Solvable *s) } } } - if (s->repo == installed && solvable_lookup_idarray(s, SOLVABLE_TRIGGERS, &reqq) && reqq.count) + if (s->recommends && s->repo != installed) + { + Id rec, *recp; + recp = s->repo->idarraydata + s->recommends; + while ((rec = *recp++) != 0) + { + queue_empty(&depq); + FOR_PROVIDES(p2, pp2, rec) + { + s2 = pool->solvables + p2; + if (p2 == p) + { + depq.count = 0; /* self provides */ + break; + } + if (s2->repo == installed && !MAPTST(&trans->transactsmap, p2)) + continue; + if (s2->repo != installed && !MAPTST(&trans->transactsmap, p2)) + continue; /* package stays uninstalled */ + if (s2->repo != installed) + queue_pushunique(&depq, p2); + } + for (i = 0; i < depq.count; i++) + { + p2 = depq.elements[i]; + if (pool->solvables[p2].repo != installed) + { +#if 0 + printf("add recommends inst->inst edge (%s -> %s -> %s)\n", pool_solvid2str(pool, p), pool_dep2str(pool, rec), pool_solvid2str(pool, p2)); +#endif + addedge(od, p, p2, TYPE_REC); + } + } + } + } + if (s->suggests && s->repo != installed) + { + Id sug, *sugp; + sugp = s->repo->idarraydata + s->suggests; + while ((sug = *sugp++) != 0) + { + queue_empty(&depq); + FOR_PROVIDES(p2, pp2, sug) + { + s2 = pool->solvables + p2; + if (p2 == p) + { + depq.count = 0; /* self provides */ + break; + } + if (s2->repo == installed && !MAPTST(&trans->transactsmap, p2)) + continue; + if (s2->repo != installed && !MAPTST(&trans->transactsmap, p2)) + continue; /* package stays uninstalled */ + if (s2->repo != installed) + queue_pushunique(&depq, p2); + } + for (i = 0; i < depq.count; i++) + { + p2 = depq.elements[i]; + if (pool->solvables[p2].repo != installed) + { +#if 0 + printf("add suggests inst->inst edge (%s -> %s -> %s)\n", pool_solvid2str(pool, p), pool_dep2str(pool, sug), pool_solvid2str(pool, p2)); +#endif + addedge(od, p, p2, TYPE_SUG); + } + } + } + } + if (s->repo == installed && solvable_lookup_idarray(s, SOLVABLE_TRIGGERS, &depq) && depq.count) { /* we're getting deinstalled/updated. Try to do this before our * triggers are hit */ - for (i = 0; i < reqq.count; i++) + for (i = 0; i < depq.count; i++) { - Id tri = reqq.elements[i]; + Id tri = depq.elements[i]; FOR_PROVIDES(p2, pp2, tri) { if (p2 == p) @@ -462,7 +515,7 @@ addsolvableedges(struct orderdata *od, Solvable *s) } } } - queue_free(&reqq); + queue_free(&depq); } @@ -473,7 +526,7 @@ breakcycle(struct orderdata *od, Id *cycle) Pool *pool = od->trans->pool; Id ddegmin, ddegmax, ddeg; int k, l; - struct _TransactionElement *te; + struct s_TransactionElement *te; l = 0; ddegmin = ddegmax = 0; @@ -540,13 +593,14 @@ breakcycle(struct orderdata *od, Id *cycle) POOL_DEBUG(SOLV_DEBUG_STATS, "\n"); } +#if 0 static inline void dump_tes(struct orderdata *od) { Pool *pool = od->trans->pool; int i, j; Queue obsq; - struct _TransactionElement *te, *te2; + struct s_TransactionElement *te, *te2; queue_init(&obsq); for (i = 1, te = od->tes + i; i < od->ntes; i++, te++) @@ -570,11 +624,12 @@ dump_tes(struct orderdata *od) } } } +#endif static void reachable(struct orderdata *od, Id i) { - struct _TransactionElement *te = od->tes + i; + struct s_TransactionElement *te = od->tes + i; int j, k; if (te->mark != 0) @@ -602,7 +657,7 @@ addcycleedges(struct orderdata *od, Id *cycle, Queue *todo) Transaction *trans = od->trans; Pool *pool = trans->pool; #endif - struct _TransactionElement *te; + struct s_TransactionElement *te; int i, j, k, tail; int head; @@ -722,7 +777,7 @@ transaction_order(Transaction *trans, int flags) Solvable *s; int i, j, k, numte, numedge; struct orderdata od; - struct _TransactionElement *te; + struct s_TransactionElement *te; Queue todo, obsq, samerepoq, uninstq; int cycstart, cycel; Id *cycle; @@ -737,7 +792,7 @@ transaction_order(Transaction *trans, int flags) /* free old data if present */ if (trans->orderdata) { - struct _TransactionOrderdata *od = trans->orderdata; + struct s_TransactionOrderdata *od = trans->orderdata; od->tes = solv_free(od->tes); od->invedgedata = solv_free(od->invedgedata); trans->orderdata = solv_free(trans->orderdata); @@ -1008,10 +1063,9 @@ transaction_order(Transaction *trans, int flags) #if 0 printf("do %s [%d]\n", pool_solvid2str(pool, te->p), temedianr[i]); #endif - s = pool->solvables + te->p; for (j = te->edges; od.invedgedata[j]; j++) { - struct _TransactionElement *te2 = od.tes + od.invedgedata[j]; + struct s_TransactionElement *te2 = od.tes + od.invedgedata[j]; assert(te2->mark > 0); if (--te2->mark == 0) { @@ -1045,7 +1099,7 @@ printf("free %s [%d]\n", pool_solvid2str(pool, te2->p), temedianr[od.invedgedata if ((flags & (SOLVER_TRANSACTION_KEEP_ORDERDATA | SOLVER_TRANSACTION_KEEP_ORDERCYCLES)) != 0) { - struct _TransactionOrderdata *tod; + struct s_TransactionOrderdata *tod; trans->orderdata = tod = solv_calloc(1, sizeof(*trans->orderdata)); if ((flags & SOLVER_TRANSACTION_KEEP_ORDERCYCLES) != 0) { @@ -1079,8 +1133,8 @@ int transaction_order_add_choices(Transaction *trans, Id chosen, Queue *choices) { int i, j; - struct _TransactionOrderdata *od = trans->orderdata; - struct _TransactionElement *te; + struct s_TransactionOrderdata *od = trans->orderdata; + struct s_TransactionElement *te; if (!od) return choices->count; @@ -1262,8 +1316,10 @@ transaction_check_order(Transaction *trans) map_init(&ins, pool->nsolvables); map_init(&seen, pool->nsolvables); if (pool->installed) - FOR_REPO_SOLVABLES(pool->installed, p, s) - MAPSET(&ins, p); + { + FOR_REPO_SOLVABLES(pool->installed, p, s) + MAPSET(&ins, p); + } lastins = 0; for (i = 0; i < trans->steps.count; i++) { @@ -1289,7 +1345,7 @@ transaction_check_order(Transaction *trans) void transaction_order_get_cycleids(Transaction *trans, Queue *q, int minseverity) { - struct _TransactionOrderdata *od = trans->orderdata; + struct s_TransactionOrderdata *od = trans->orderdata; Queue *cq; int i, cid, ncycles; @@ -1317,7 +1373,7 @@ transaction_order_get_cycleids(Transaction *trans, Queue *q, int minseverity) int transaction_order_get_cycle(Transaction *trans, Id cid, Queue *q) { - struct _TransactionOrderdata *od = trans->orderdata; + struct s_TransactionOrderdata *od = trans->orderdata; Queue *cq; int cmin, cmax, severity; int ncycles;