X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fpool.c;h=e375b915c4989b541f8b57c8e2a37c8a5e2880e1;hb=42f00b0f81834d61893165bf2486ee2771fe2446;hp=1761d42d51e8267e332511b5554f67331d73095c;hpb=2a270f741c5123d4aa7ec409be09da5498d754a5;p=platform%2Fupstream%2Flibsolv.git diff --git a/src/pool.c b/src/pool.c index 1761d42..e375b91 100644 --- a/src/pool.c +++ b/src/pool.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Novell Inc. + * Copyright (c) 2007-2009, Novell Inc. * * This program is licensed under the BSD license, read LICENSE.BSD * for further information @@ -123,13 +123,20 @@ pool_free_solvable_block(Pool *pool, Id start, int count, int reuseids) } -static Pool *pool_shrink_whatprovides_sortcmp_data; +void +pool_set_installed(Pool *pool, Repo *installed) +{ + if (pool->installed == installed) + return; + pool->installed = installed; + pool_freewhatprovides(pool); +} static int -pool_shrink_whatprovides_sortcmp(const void *ap, const void *bp) +pool_shrink_whatprovides_sortcmp(const void *ap, const void *bp, void *dp) { int r; - Pool *pool = pool_shrink_whatprovides_sortcmp_data; + Pool *pool = dp; Id oa, ob, *da, *db; oa = pool->whatprovides[*(Id *)ap]; ob = pool->whatprovides[*(Id *)bp]; @@ -169,8 +176,7 @@ pool_shrink_whatprovides(Pool *pool) sorted = sat_malloc2(pool->ss.nstrings, sizeof(Id)); for (id = 0; id < pool->ss.nstrings; id++) sorted[id] = id; - pool_shrink_whatprovides_sortcmp_data = pool; - qsort(sorted + 1, pool->ss.nstrings - 1, sizeof(Id), pool_shrink_whatprovides_sortcmp); + sat_sort(sorted + 1, pool->ss.nstrings - 1, sizeof(Id), pool_shrink_whatprovides_sortcmp, pool); last = 0; lastid = 0; for (i = 1; i < pool->ss.nstrings; i++) @@ -251,7 +257,10 @@ pool_createwhatprovides(Pool *pool) Offset *idp, n; Offset *whatprovides; Id *whatprovidesdata, *d; + Repo *installed = pool->installed; + unsigned int now; + now = sat_timems(0); POOL_DEBUG(SAT_DEBUG_STATS, "number of solvables: %d\n", pool->nsolvables); POOL_DEBUG(SAT_DEBUG_STATS, "number of ids: %d + %d\n", pool->ss.nstrings, pool->nrels); @@ -268,7 +277,9 @@ pool_createwhatprovides(Pool *pool) s = pool->solvables + i; if (!s->provides) continue; - if (!pool_installable(pool, s)) + /* we always need the installed solvable in the whatprovides data, + otherwise obsoletes/conflicts on them won't work */ + if (s->repo != installed && !pool_installable(pool, s)) continue; pp = s->repo->idarraydata + s->provides; while ((id = *pp++) != ID_NULL) @@ -314,7 +325,7 @@ pool_createwhatprovides(Pool *pool) s = pool->solvables + i; if (!s->provides) continue; - if (!pool_installable(pool, s)) + if (s->repo != installed && !pool_installable(pool, s)) continue; /* for all provides of this solvable */ @@ -342,11 +353,14 @@ pool_createwhatprovides(Pool *pool) pool->whatprovidesdataoff = off; pool->whatprovidesdataleft = extra; pool_shrink_whatprovides(pool); + POOL_DEBUG(SAT_DEBUG_STATS, "whatprovides memory used: %d K id array, %d K data\n", (pool->ss.nstrings + pool->nrels + WHATPROVIDES_BLOCK) / (int)(1024/sizeof(Id)), (pool->whatprovidesdataoff + pool->whatprovidesdataleft) / (int)(1024/sizeof(Id))); + POOL_DEBUG(SAT_DEBUG_STATS, "createwhatprovides took %d ms\n", sat_timems(now)); } /* * free all of our whatprovides data - * be careful, everything internalized with pool_queuetowhatprovides is gone, too + * be careful, everything internalized with pool_queuetowhatprovides is + * gone, too */ void pool_freewhatprovides(Pool *pool) @@ -443,8 +457,65 @@ pool_match_nevr_rel(Pool *pool, Solvable *s, Id d) return 1; if (flags != 2 && flags != 5) flags ^= 5; +#ifdef DEBIAN_SEMANTICS + if ((flags & (1 << (1 + evrcmp(pool, s->evr, evr, EVRCMP_COMPARE)))) != 0) + return 1; +#else if ((flags & (1 << (1 + evrcmp(pool, s->evr, evr, EVRCMP_MATCH_RELEASE)))) != 0) return 1; +#endif + return 0; +} + +/* match two dependencies */ + +int +pool_match_dep(Pool *pool, Id d1, Id d2) +{ + Reldep *rd1, *rd2; + int pflags, flags; + + if (d1 == d2) + return 1; + if (!ISRELDEP(d1)) + { + if (!ISRELDEP(d2)) + return 0; + rd2 = GETRELDEP(pool, d2); + return pool_match_dep(pool, d1, rd2->name); + } + rd1 = GETRELDEP(pool, d1); + if (!ISRELDEP(d2)) + { + return pool_match_dep(pool, rd1->name, d2); + } + rd2 = GETRELDEP(pool, d2); + if (!pool_match_dep(pool, rd1->name, rd2->name)) + return 0; + pflags = rd1->flags; + flags = rd2->flags; + if (!pflags || !flags || pflags >= 8 || flags >= 8) + return 0; + if (flags == 7 || pflags == 7) + return 1; + if ((pflags & flags & 5) != 0) + return 1; + if (rd1->evr == rd2->evr) + { + if ((pflags & flags & 2) != 0) + return 1; + } + else + { + int f = flags == 5 ? 5 : flags == 2 ? pflags : (flags ^ 5) & (pflags | 5); +#ifdef DEBIAN_SEMANTICS + if ((f & (1 << (1 + evrcmp(pool, rd1->evr, rd2->evr, EVRCMP_COMPARE)))) != 0) + return 1; +#else + if ((f & (1 << (1 + evrcmp(pool, rd1->evr, rd2->evr, EVRCMP_MATCH_RELEASE)))) != 0) + return 1; +#endif + } return 0; } @@ -456,7 +527,7 @@ pool_match_nevr_rel(Pool *pool, Solvable *s, Id d) * */ -Id * +Id pool_addrelproviders(Pool *pool, Id d) { Reldep *rd = GETRELDEP(pool, d); @@ -467,7 +538,7 @@ pool_addrelproviders(Pool *pool, Id d) Id evr = rd->evr; int flags = rd->flags; Id pid, *pidp; - Id p, *pp, *pp2, *pp3; + Id p, wp, *pp, *pp2, *pp3; d = GETRELID(d); queue_init_buffer(&plist, buf, sizeof(buf)/sizeof(*buf)); @@ -475,8 +546,8 @@ pool_addrelproviders(Pool *pool, Id d) { case REL_AND: case REL_WITH: - pp = pool_whatprovides(pool, name); - pp2 = pool_whatprovides(pool, evr); + pp = pool_whatprovides_ptr(pool, name); + pp2 = pool_whatprovides_ptr(pool, evr); while ((p = *pp++) != 0) { for (pp3 = pp2; *pp3;) @@ -488,14 +559,20 @@ pool_addrelproviders(Pool *pool, Id d) } break; case REL_OR: - pp = pool_whatprovides(pool, name); + pp = pool_whatprovides_ptr(pool, name); while ((p = *pp++) != 0) queue_push(&plist, p); - pp = pool_whatprovides(pool, evr); + pp = pool_whatprovides_ptr(pool, evr); while ((p = *pp++) != 0) queue_pushunique(&plist, p); break; case REL_NAMESPACE: + if (name == NAMESPACE_OTHERPROVIDERS) + { + wp = pool_whatprovides(pool, evr); + pool->whatprovides_rel[d] = wp; + return wp; + } if (pool->nscallback) { /* ask callback which packages provide the dependency @@ -508,7 +585,7 @@ pool_addrelproviders(Pool *pool, Id d) { queue_free(&plist); pool->whatprovides_rel[d] = p; - return pool->whatprovidesdata + p; + return p; } if (p == 1) queue_push(&plist, SYSTEMSOLVABLE); @@ -531,17 +608,21 @@ pool_addrelproviders(Pool *pool, Id d) } break; } - pp = pp2 = pool_whatprovides(pool, name); + wp = pool_whatprovides(pool, name); + pp = pool->whatprovidesdata + wp; while ((p = *pp++) != 0) { Solvable *s = pool->solvables + p; if (s->arch == evr) queue_push(&plist, p); else - pp2 = 0; + wp = 0; + } + if (wp) + { + pool->whatprovides_rel[d] = wp; + return wp; } - if (pp2) - return pp2; break; default: break; @@ -553,7 +634,7 @@ pool_addrelproviders(Pool *pool, Id d) #endif if (flags && flags < 8) { - pp = pool_whatprovides(pool, name); + pp = pool_whatprovides_ptr(pool, name); while (ISRELDEP(name)) { rd = GETRELDEP(pool, name); @@ -610,8 +691,13 @@ pool_addrelproviders(Pool *pool, Id d) else { int f = flags == 5 ? 5 : flags == 2 ? pflags : (flags ^ 5) & (pflags | 5); +#ifdef DEBIAN_SEMANTICS + if ((f & (1 << (1 + evrcmp(pool, pevr, evr, EVRCMP_COMPARE)))) != 0) + break; +#else if ((f & (1 << (1 + evrcmp(pool, pevr, evr, EVRCMP_MATCH_RELEASE)))) != 0) break; +#endif } } if (!pid) @@ -629,7 +715,7 @@ pool_addrelproviders(Pool *pool, Id d) pool->whatprovides_rel[d] = pool_queuetowhatprovides(pool, &plist); queue_free(&plist); - return pool->whatprovidesdata + pool->whatprovides_rel[d]; + return pool->whatprovides_rel[d]; } /*************************************************************************/ @@ -800,16 +886,26 @@ addfileprovides_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyV return 0; } +static int +addfileprovides_setid_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv) +{ + Map *provideids = cbdata; + if (key->type != REPOKEY_TYPE_IDARRAY) + return 0; + MAPSET(provideids, kv->id); + return kv->eof ? SEARCH_NEXT_SOLVABLE : 0; +} + static void pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, struct searchfiles *sf, Repo *repoonly) { - Id p, start, end, *idp; + Id p, start, end; Solvable *s; Repodata *data = 0, *nextdata; Repo *oldrepo = 0; int dataincludes = 0; - int i; + int i, j; Map providedids; cbd->nfiles = sf->nfiles; @@ -832,6 +928,7 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru { if (!s->repo || (repoonly && s->repo != repoonly)) continue; + /* check if p is in (oldrepo,data) */ if (s->repo != oldrepo || (data && p >= data->end)) { data = 0; @@ -839,28 +936,35 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru } if (oldrepo == 0) { + /* nope, find new repo/repodata */ + /* if we don't find a match, set data to the next repodata */ nextdata = 0; for (i = 0, data = s->repo->repodata; i < s->repo->nrepodata; i++, data++) { - if (!data->addedfileprovides || p >= data->end) + if (p >= data->end) continue; + if (data->state != REPODATA_AVAILABLE) + continue; + for (j = 1; j < data->nkeys; j++) + if (data->keys[j].name == REPOSITORY_ADDEDFILEPROVIDES && data->keys[j].type == REPOKEY_TYPE_IDARRAY) + break; + if (j == data->nkeys) + continue; + /* great, this repodata contains addedfileprovides */ if (!nextdata || nextdata->start > data->start) nextdata = data; if (p >= data->start) break; } if (i == s->repo->nrepodata) - data = nextdata; + data = nextdata; /* no direct hit, use next repodata */ if (data) { map_init(&providedids, pool->ss.nstrings); - for (idp = data->addedfileprovides; *idp; idp++) - MAPSET(&providedids, *idp); + repodata_search(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, 0, addfileprovides_setid_cb, &providedids); for (i = 0; i < cbd->nfiles; i++) if (!MAPTST(&providedids, cbd->ids[i])) - { - break; - } + break; map_free(&providedids); dataincludes = i == cbd->nfiles; } @@ -961,9 +1065,9 @@ pool_addfileprovides_ids(Pool *pool, Repo *installed, Id **idp) } void -pool_addfileprovides(Pool *pool, Repo *installed) +pool_addfileprovides(Pool *pool) { - pool_addfileprovides_ids(pool, installed, 0); + pool_addfileprovides_ids(pool, pool->installed, 0); } void @@ -981,6 +1085,12 @@ pool_search(Pool *pool, Id p, Id key, const char *match, int flags, int (*callba repo_search(pool->solvables[p].repo, p, key, match, flags, callback, cbdata); } +void +pool_clear_pos(Pool *pool) +{ + memset(&pool->pos, 0, sizeof(pool->pos)); +} + void pool_set_languages(Pool *pool, const char **languages, int nlanguages) @@ -1154,7 +1264,7 @@ propagate_mountpoints(struct mptree *mptree, int pos, Id mountpoint) #define MPTREE_BLOCK 15 void -pool_calc_duchanges(Pool *pool, Repo *oldinstalled, Map *installedmap, DUChanges *mps, int nmps) +pool_calc_duchanges(Pool *pool, Map *installedmap, DUChanges *mps, int nmps) { char *p; const char *path, *compstr; @@ -1166,6 +1276,7 @@ pool_calc_duchanges(Pool *pool, Repo *oldinstalled, Map *installedmap, DUChanges Solvable *s; Id sp; Map ignoredu; + Repo *oldinstalled = pool->installed; memset(&ignoredu, 0, sizeof(ignoredu)); cbd.mps = mps; @@ -1254,7 +1365,7 @@ pool_calc_duchanges(Pool *pool, Repo *oldinstalled, Map *installedmap, DUChanges repo_search(s->repo, sp, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); if (!cbd.hasdu && oldinstalled) { - Id op, *opp; + Id op, opp; /* no du data available, ignore data of all installed solvables we obsolete */ if (!ignoredu.map) map_init(&ignoredu, oldinstalled->end - oldinstalled->start); @@ -1292,11 +1403,12 @@ pool_calc_duchanges(Pool *pool, Repo *oldinstalled, Map *installedmap, DUChanges } int -pool_calc_installsizechange(Pool *pool, Repo *oldinstalled, Map *installedmap) +pool_calc_installsizechange(Pool *pool, Map *installedmap) { Id sp; Solvable *s; int change = 0; + Repo *oldinstalled = pool->installed; for (sp = 1, s = pool->solvables + sp; sp < pool->nsolvables; sp++, s++) { @@ -1304,7 +1416,7 @@ pool_calc_installsizechange(Pool *pool, Repo *oldinstalled, Map *installedmap) continue; if (!MAPTST(installedmap, sp)) continue; - change += repo_lookup_num(s, SOLVABLE_INSTALLSIZE); + change += solvable_lookup_num(s, SOLVABLE_INSTALLSIZE, 0); } if (oldinstalled) { @@ -1312,7 +1424,7 @@ pool_calc_installsizechange(Pool *pool, Repo *oldinstalled, Map *installedmap) { if (MAPTST(installedmap, sp)) continue; - change -= repo_lookup_num(s, SOLVABLE_INSTALLSIZE); + change -= solvable_lookup_num(s, SOLVABLE_INSTALLSIZE, 0); } } return change; @@ -1335,14 +1447,35 @@ static inline Id dep2name(Pool *pool, Id dep) return dep; } -static inline int providedbyinstalled(Pool *pool, unsigned char *map, Id dep) +static int providedbyinstalled_multiversion(Pool *pool, unsigned char *map, Id n, Id dep) { - Id p, *pp; + Id p, pp; + Solvable *sn = pool->solvables + n; + + FOR_PROVIDES(p, pp, sn->name) + { + Solvable *s = pool->solvables + p; + if (s->name != sn->name || s->arch != sn->arch) + continue; + if ((map[p] & 9) == 9) + return 1; + } + return 0; +} + +static inline int providedbyinstalled(Pool *pool, unsigned char *map, Id dep, int ispatch, Map *noobsoletesmap) +{ + Id p, pp; int r = 0; FOR_PROVIDES(p, pp, dep) { if (p == SYSTEMSOLVABLE) return 1; /* always boring, as never constraining */ + if (ispatch && !pool_match_nevr(pool, pool->solvables + p, dep)) + continue; + if (ispatch && noobsoletesmap && noobsoletesmap->size && MAPTST(noobsoletesmap, p) && ISRELDEP(dep)) + if (providedbyinstalled_multiversion(pool, map, p, dep)) + continue; if ((map[p] & 9) == 9) return 9; r |= map[p] & 17; @@ -1362,7 +1495,7 @@ static inline int providedbyinstalled(Pool *pool, unsigned char *map, Id dep) */ void -pool_trivial_installable(Pool *pool, Repo *oldinstalled, Map *installedmap, Queue *pkgs, Queue *res) +pool_trivial_installable_noobsoletesmap(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res, Map *noobsoletesmap) { int i, r, m, did; Id p, *dp, con, *conp, req, *reqp; @@ -1381,7 +1514,7 @@ pool_trivial_installable(Pool *pool, Repo *oldinstalled, Map *installedmap, Queu conp = s->repo->idarraydata + s->conflicts; while ((con = *conp++) != 0) { - dp = pool_whatprovides(pool, con); + dp = pool_whatprovides_ptr(pool, con); for (; *dp; dp++) map[p] |= 2; /* XXX: self conflict ? */ } @@ -1410,7 +1543,7 @@ pool_trivial_installable(Pool *pool, Repo *oldinstalled, Map *installedmap, Queu { if (req == SOLVABLE_PREREQMARKER) continue; - r = providedbyinstalled(pool, map, req); + r = providedbyinstalled(pool, map, req, 0, 0); if (!r) { /* decided and miss */ @@ -1426,10 +1559,14 @@ pool_trivial_installable(Pool *pool, Repo *oldinstalled, Map *installedmap, Queu } if (s->conflicts) { + int ispatch = 0; /* see solver.c patch handling */ + + if (!strncmp("patch:", id2str(pool, s->name), 6)) + ispatch = 1; conp = s->repo->idarraydata + s->conflicts; while ((con = *conp++) != 0) { - if ((providedbyinstalled(pool, map, con) & 1) != 0) + if ((providedbyinstalled(pool, map, con, ispatch, noobsoletesmap) & 1) != 0) { map[p] = 2; break; @@ -1437,7 +1574,7 @@ pool_trivial_installable(Pool *pool, Repo *oldinstalled, Map *installedmap, Queu if ((m == 1 || m == 17) && ISRELDEP(con)) { con = dep2name(pool, con); - if ((providedbyinstalled(pool, map, con) & 1) != 0) + if ((providedbyinstalled(pool, map, con, ispatch, noobsoletesmap) & 1) != 0) m = 9; } } @@ -1454,7 +1591,7 @@ pool_trivial_installable(Pool *pool, Repo *oldinstalled, Map *installedmap, Queu obsp = s->repo->idarraydata + s->obsoletes; while ((obs = *obsp++) != 0) { - if ((providedbyinstalled(pool, map, obs) & 1) != 0) + if ((providedbyinstalled(pool, map, obs, 0, 0) & 1) != 0) { map[p] = 2; break; @@ -1478,7 +1615,7 @@ pool_trivial_installable(Pool *pool, Repo *oldinstalled, Map *installedmap, Queu #endif if (m != map[p]) { - map[p] = m; + map[p] = m; did = 0; } } @@ -1498,4 +1635,10 @@ pool_trivial_installable(Pool *pool, Repo *oldinstalled, Map *installedmap, Queu free(map); } +void +pool_trivial_installable(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res) +{ + pool_trivial_installable_noobsoletesmap(pool, installedmap, pkgs, res, 0); +} + // EOF