X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fpool.c;h=4b6ab433f90b710194c7e4cd959148c8f68bdf58;hb=eef58960087e9d7b347e77629b0da03b656b8377;hp=b6586d01a9ead13bd4cbabb85b271281eed7ca32;hpb=09f29f706df0cf171ba7e7e8a3272388039630e4;p=platform%2Fupstream%2Flibsolv.git diff --git a/src/pool.c b/src/pool.c index b6586d0..4b6ab43 100644 --- a/src/pool.c +++ b/src/pool.c @@ -53,26 +53,35 @@ pool_create(void) pool->solvables = solv_extend_resize(0, 2, sizeof(Solvable), SOLVABLE_BLOCK); pool->nsolvables = 2; memset(pool->solvables, 0, 2 * sizeof(Solvable)); + + queue_init(&pool->vendormap); + +#if defined(DEBIAN) + pool->disttype = DISTTYPE_DEB; + pool->noarchid = ARCH_ALL; +#elif defined(ARCHLINUX) + pool->disttype = DISTTYPE_ARCH; + pool->noarchid = ARCH_ANY; +#else + pool->disttype = DISTTYPE_RPM; + pool->noarchid = ARCH_NOARCH; +#endif + + /* initialize the system solvable */ s = pool->solvables + SYSTEMSOLVABLE; s->name = SYSTEM_SYSTEM; - s->arch = ARCH_NOARCH; + s->arch = pool->noarchid; s->evr = ID_EMPTY; - queue_init(&pool->vendormap); - pool->debugmask = SOLV_DEBUG_RESULT; /* FIXME */ #ifdef FEDORA pool->obsoleteusescolors = 1; #endif -#ifdef DEBIAN - pool->allowselfconflicts = 1; -# ifdef MULTI_SEMANTICS - pool->disttype = DISTTYPE_DEB; -# endif -#endif #ifdef RPM5 + pool->forbidselfconflicts = 1; pool->obsoleteusesprovides = 1; pool->implicitobsoleteusesprovides = 1; + pool->havedistepoch = 1; #endif return pool; } @@ -86,8 +95,9 @@ pool_free(Pool *pool) pool_freewhatprovides(pool); pool_freeidhashes(pool); - repo_freeallrepos(pool, 1); + pool_freeallrepos(pool, 1); solv_free(pool->id2arch); + solv_free(pool->id2color); solv_free(pool->solvables); stringpool_free(&pool->ss); solv_free(pool->rels); @@ -99,17 +109,101 @@ pool_free(Pool *pool) free((char *)pool->languages[i]); solv_free(pool->languages); solv_free(pool->languagecache); + solv_free(pool->errstr); + solv_free(pool->rootdir); solv_free(pool); } +void +pool_freeallrepos(Pool *pool, int reuseids) +{ + int i; + + pool_freewhatprovides(pool); + for (i = 1; i < pool->nrepos; i++) + if (pool->repos[i]) + repo_freedata(pool->repos[i]); + pool->repos = solv_free(pool->repos); + pool->nrepos = 0; + pool->urepos = 0; + /* the first two solvables don't belong to a repo */ + pool_free_solvable_block(pool, 2, pool->nsolvables - 2, reuseids); +} + #ifdef MULTI_SEMANTICS void pool_setdisttype(Pool *pool, int disttype) { pool->disttype = disttype; + if (disttype == DISTTYPE_RPM) + pool->noarchid = ARCH_NOARCH; + if (disttype == DISTTYPE_DEB) + pool->noarchid = ARCH_ALL; + if (disttype == DISTTYPE_ARCH) + pool->noarchid = ARCH_ANY; + pool->solvables[SYSTEMSOLVABLE].arch = pool->noarchid; } #endif +int +pool_get_flag(Pool *pool, int flag) +{ + switch (flag) + { + case POOL_FLAG_PROMOTEEPOCH: + return pool->promoteepoch; + case POOL_FLAG_FORBIDSELFCONFLICTS: + return pool->forbidselfconflicts; + case POOL_FLAG_OBSOLETEUSESPROVIDES: + return pool->obsoleteusesprovides; + case POOL_FLAG_IMPLICITOBSOLETEUSESPROVIDES: + return pool->implicitobsoleteusesprovides; + case POOL_FLAG_OBSOLETEUSESCOLORS: + return pool->obsoleteusescolors; + case POOL_FLAG_NOINSTALLEDOBSOLETES: + return pool->noinstalledobsoletes; + case POOL_FLAG_HAVEDISTEPOCH: + return pool->havedistepoch; + default: + break; + } + return -1; +} + +int +pool_set_flag(Pool *pool, int flag, int value) +{ + int old = pool_get_flag(pool, flag); + switch (flag) + { + case POOL_FLAG_PROMOTEEPOCH: + pool->promoteepoch = value; + break; + case POOL_FLAG_FORBIDSELFCONFLICTS: + pool->forbidselfconflicts = value; + break; + case POOL_FLAG_OBSOLETEUSESPROVIDES: + pool->obsoleteusesprovides = value; + break; + case POOL_FLAG_IMPLICITOBSOLETEUSESPROVIDES: + pool->implicitobsoleteusesprovides = value; + break; + case POOL_FLAG_OBSOLETEUSESCOLORS: + pool->obsoleteusescolors = value; + break; + case POOL_FLAG_NOINSTALLEDOBSOLETES: + pool->noinstalledobsoletes = value; + break; + case POOL_FLAG_HAVEDISTEPOCH: + pool->havedistepoch = value; + break; + default: + break; + } + return old; +} + + Id pool_add_solvable(Pool *pool) { @@ -164,10 +258,6 @@ pool_shrink_whatprovides_sortcmp(const void *ap, const void *bp, void *dp) ob = pool->whatprovides[*(Id *)bp]; if (oa == ob) return *(Id *)ap - *(Id *)bp; - if (!oa) - return -1; - if (!ob) - return 1; da = pool->whatprovidesdata + oa; db = pool->whatprovidesdata + ob; while (*db) @@ -187,7 +277,7 @@ pool_shrink_whatprovides_sortcmp(const void *ap, const void *bp, void *dp) static void pool_shrink_whatprovides(Pool *pool) { - Id i, id; + Id i, n, id; Id *sorted; Id lastid, *last, *dp, *lp; Offset o; @@ -196,17 +286,17 @@ pool_shrink_whatprovides(Pool *pool) if (pool->ss.nstrings < 3) return; sorted = solv_malloc2(pool->ss.nstrings, sizeof(Id)); - for (id = 0; id < pool->ss.nstrings; id++) - sorted[id] = id; - solv_sort(sorted + 1, pool->ss.nstrings - 1, sizeof(Id), pool_shrink_whatprovides_sortcmp, pool); + for (i = id = 0; id < pool->ss.nstrings; id++) + if (pool->whatprovides[id] && pool->whatprovides[id] != 1) + sorted[i++] = id; + n = i; + solv_sort(sorted, n, sizeof(Id), pool_shrink_whatprovides_sortcmp, pool); last = 0; lastid = 0; - for (i = 1; i < pool->ss.nstrings; i++) + for (i = 0; i < n; i++) { id = sorted[i]; o = pool->whatprovides[id]; - if (o == 0 || o == 1) - continue; dp = pool->whatprovidesdata + o; if (last) { @@ -283,8 +373,11 @@ pool_createwhatprovides(Pool *pool) unsigned int now; now = solv_timems(0); - POOL_DEBUG(SOLV_DEBUG_STATS, "number of solvables: %d\n", pool->nsolvables); + POOL_DEBUG(SOLV_DEBUG_STATS, "number of solvables: %d, memory used: %d K\n", pool->nsolvables, pool->nsolvables * (int)sizeof(Solvable) / 1024); POOL_DEBUG(SOLV_DEBUG_STATS, "number of ids: %d + %d\n", pool->ss.nstrings, pool->nrels); + POOL_DEBUG(SOLV_DEBUG_STATS, "string memory used: %d K array + %d K data, rel memory used: %d K array\n", pool->ss.nstrings / (1024 / (int)sizeof(Id)), pool->ss.sstrings / 1024, pool->nrels * (int)sizeof(Reldep) / 1024); + if (pool->ss.stringhashmask || pool->relhashmask) + POOL_DEBUG(SOLV_DEBUG_STATS, "string hash memory: %d K, rel hash memory : %d K\n", (pool->ss.stringhashmask + 1) / (int)(1024/sizeof(Id)), (pool->relhashmask + 1) / (int)(1024/sizeof(Id))); pool_freeidhashes(pool); /* XXX: should not be here! */ pool_freewhatprovides(pool); @@ -435,7 +528,7 @@ pool_queuetowhatprovides(Pool *pool, Queue *q) #if defined(MULTI_SEMANTICS) # define EVRCMP_DEPCMP (pool->disttype == DISTTYPE_DEB ? EVRCMP_COMPARE : EVRCMP_MATCH_RELEASE) -#elif defined(DEBIAN_SEMANTICS) +#elif defined(DEBIAN) # define EVRCMP_DEPCMP EVRCMP_COMPARE #else # define EVRCMP_DEPCMP EVRCMP_MATCH_RELEASE @@ -457,7 +550,10 @@ pool_match_nevr_rel(Pool *pool, Solvable *s, Id d) { case REL_ARCH: if (s->arch != evr) - return 0; + { + if (evr != ARCH_SRC || s->arch != ARCH_NOSRC) + return 0; + } return pool_match_nevr(pool, s, name); case REL_OR: if (pool_match_nevr(pool, s, name)) @@ -475,15 +571,26 @@ pool_match_nevr_rel(Pool *pool, Solvable *s, Id d) if (!pool_match_nevr(pool, s, name)) return 0; if (evr == s->evr) - return flags & 2 ? 1 : 0; + return (flags & REL_EQ) ? 1 : 0; if (!flags) return 0; if (flags == 7) return 1; - if (flags != 2 && flags != 5) - flags ^= 5; - if ((flags & (1 << (1 + pool_evrcmp(pool, s->evr, evr, EVRCMP_DEPCMP)))) != 0) - return 1; + switch (pool_evrcmp(pool, s->evr, evr, EVRCMP_DEPCMP)) + { + case -2: + return 1; + case -1: + return (flags & REL_LT) ? 1 : 0; + case 0: + return (flags & REL_EQ) ? 1 : 0; + case 1: + return (flags & REL_GT) ? 1 : 0; + case 2: + return (flags & REL_EQ) ? 1 : 0; + default: + break; + } return 0; } @@ -495,18 +602,24 @@ pool_match_flags_evr(Pool *pool, int pflags, Id pevr, int flags, int evr) return 0; if (flags == 7 || pflags == 7) return 1; /* rel provides every version */ - if ((pflags & flags & 5) != 0) + if ((pflags & flags & (REL_LT | REL_GT)) != 0) return 1; /* both rels show in the same direction */ if (pevr == evr) + return (flags & pflags & REL_EQ) ? 1 : 0; + switch (pool_evrcmp(pool, pevr, evr, EVRCMP_DEPCMP)) { - if ((pflags & flags & 2) != 0) - return 1; /* both have '=', match */ - } - else - { - int f = flags == 5 ? 5 : flags == 2 ? pflags : (flags ^ 5) & (pflags | 5); - if ((f & (1 << (1 + pool_evrcmp(pool, pevr, evr, EVRCMP_DEPCMP)))) != 0) - return 1; + case -2: + return (pflags & REL_EQ) ? 1 : 0; + case -1: + return (flags & REL_LT) || (pflags & REL_GT) ? 1 : 0; + case 0: + return (flags & pflags & REL_EQ) ? 1 : 0; + case 1: + return (flags & REL_GT) || (pflags & REL_LT) ? 1 : 0; + case 2: + return (flags & REL_EQ) ? 1 : 0; + default: + break; } return 0; } @@ -631,12 +744,14 @@ pool_addrelproviders(Pool *pool, Id d) * we have to iterate over the solvables as src packages do not * provide anything, thus they are not indexed in our * whatprovides hash */ - if (evr == ARCH_SRC) + if (evr == ARCH_SRC || evr == ARCH_NOSRC) { Solvable *s; for (p = 1, s = pool->solvables + p; p < pool->nsolvables; p++, s++) { - if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) + if (!s->repo) + continue; + if (s->arch != evr && s->arch != ARCH_NOSRC) continue; if (pool_match_nevr(pool, s, name)) queue_push(&plist, p); @@ -707,22 +822,14 @@ pool_addrelproviders(Pool *pool, Id d) pidp = s->repo->idarraydata + s->provides; while ((pid = *pidp++) != 0) { - if (pid == name) + if (!ISRELDEP(pid)) { -#if defined(MULTI_SEMANTICS) + if (pid != name) + continue; /* wrong provides name */ if (pool->disttype == DISTTYPE_DEB) - continue; - else - break; -#elif defined(DEBIAN_SEMANTICS) - continue; /* unversioned provides can - * never match versioned deps */ -#else - break; /* yes, provides all versions */ -#endif + continue; /* unversioned provides can never match versioned deps */ + break; } - if (!ISRELDEP(pid)) - continue; /* wrong provides name */ prd = GETRELDEP(pool, pid); if (prd->name != name) continue; /* wrong provides name */ @@ -771,15 +878,56 @@ pool_debug(Pool *pool, int type, const char *format, ...) return; } vsnprintf(buf, sizeof(buf), format, args); + va_end(args); pool->debugcallback(pool, pool->debugcallbackdata, type, buf); } +int +pool_error(Pool *pool, int ret, const char *format, ...) +{ + va_list args; + int l; + va_start(args, format); + if (!pool->errstr) + { + pool->errstra = 1024; + pool->errstr = solv_malloc(pool->errstra); + } + if (!*format) + { + *pool->errstr = 0; + l = 0; + } + else + l = vsnprintf(pool->errstr, pool->errstra, format, args); + va_end(args); + if (l >= 0 && l + 1 > pool->errstra) + { + pool->errstra = l + 256; + pool->errstr = solv_realloc(pool->errstr, pool->errstra); + va_start(args, format); + l = vsnprintf(pool->errstr, pool->errstra, format, args); + va_end(args); + } + if (l < 0) + strcpy(pool->errstr, "unknown error"); + if (pool->debugmask & SOLV_ERROR) + pool_debug(pool, SOLV_ERROR, "%s\n", pool->errstr); + return ret; +} + +char * +pool_errstr(Pool *pool) +{ + return pool->errstr ? pool->errstr : "no error"; +} + void pool_setdebuglevel(Pool *pool, int level) { int mask = SOLV_DEBUG_RESULT; if (level > 0) - mask |= SOLV_DEBUG_STATS|SOLV_DEBUG_ANALYZE|SOLV_DEBUG_UNSOLVABLE|SOLV_DEBUG_SOLVER|SOLV_DEBUG_TRANSACTION; + mask |= SOLV_DEBUG_STATS|SOLV_DEBUG_ANALYZE|SOLV_DEBUG_UNSOLVABLE|SOLV_DEBUG_SOLVER|SOLV_DEBUG_TRANSACTION|SOLV_ERROR; if (level > 1) mask |= SOLV_DEBUG_JOB|SOLV_DEBUG_SOLUTIONS|SOLV_DEBUG_POLICY; if (level > 2) @@ -883,7 +1031,7 @@ pool_addfileprovides_dep(Pool *pool, Id *ida, struct searchfiles *sf, struct sea csf->names = solv_extend(csf->names, csf->nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK); csf->ids[csf->nfiles] = dep; sr = strrchr(s, '/'); - csf->names[csf->nfiles] = strdup(sr + 1); + csf->names[csf->nfiles] = solv_strdup(sr + 1); csf->dirs[csf->nfiles] = solv_malloc(sr - s + 1); if (sr != s) strncpy(csf->dirs[csf->nfiles], s, sr - s); @@ -927,6 +1075,7 @@ addfileprovides_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyV if (did) MAPSET(&cbd->useddirs, did); } + repodata_free_dircache(data); } if (value->id >= data->dirpool.ndirs || !MAPTST(&cbd->useddirs, value->id)) return 0; @@ -955,7 +1104,7 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru Map donemap; int ndone, incomplete; - if (!pool->nrepos) + if (!pool->urepos) return; cbd->nfiles = sf->nfiles; @@ -965,14 +1114,14 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru cbd->dids = solv_realloc2(cbd->dids, sf->nfiles, sizeof(Id)); map_init(&cbd->providedids, pool->ss.nstrings); - repoid = 0; - repo = repoonly ? repoonly : pool->repos[0]; + repoid = 1; + repo = repoonly ? repoonly : pool->repos[repoid]; map_init(&donemap, pool->nsolvables); queue_init(&fileprovidesq); provstart = provend = 0; for (;;) { - if (repo->disabled) + if (!repo || repo->disabled) { if (repoonly || ++repoid == pool->nrepos) break; @@ -1068,21 +1217,26 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru } void -pool_addfileprovides_ids(Pool *pool, Repo *installed, Id **idp) +pool_addfileprovides_queue(Pool *pool, Queue *idq, Queue *idqinst) { Solvable *s; - Repo *repo; + Repo *installed, *repo; struct searchfiles sf, isf, *isfp; struct addfileprovides_cbdata cbd; int i; unsigned int now; + installed = pool->installed; now = solv_timems(0); memset(&sf, 0, sizeof(sf)); map_init(&sf.seen, pool->ss.nstrings + pool->nrels); memset(&isf, 0, sizeof(isf)); map_init(&isf.seen, pool->ss.nstrings + pool->nrels); + if (idq) + queue_empty(idq); + if (idqinst) + queue_empty(idqinst); isfp = installed ? &isf : 0; for (i = 1, s = pool->solvables + i; i < pool->nsolvables; i++, s++) { @@ -1108,8 +1262,6 @@ pool_addfileprovides_ids(Pool *pool, Repo *installed, Id **idp) map_free(&isf.seen); POOL_DEBUG(SOLV_DEBUG_STATS, "found %d file dependencies, %d installed file dependencies\n", sf.nfiles, isf.nfiles); cbd.dids = 0; - if (idp) - *idp = 0; if (sf.nfiles) { #if 0 @@ -1117,13 +1269,12 @@ pool_addfileprovides_ids(Pool *pool, Repo *installed, Id **idp) POOL_DEBUG(SOLV_DEBUG_STATS, "looking up %s in filelist\n", pool_id2str(pool, sf.ids[i])); #endif pool_addfileprovides_search(pool, &cbd, &sf, 0); - if (idp) - { - sf.ids = solv_extend(sf.ids, sf.nfiles, 1, sizeof(Id), SEARCHFILES_BLOCK); - sf.ids[sf.nfiles] = 0; - *idp = sf.ids; - sf.ids = 0; - } + if (idq) + for (i = 0; i < sf.nfiles; i++) + queue_push(idq, sf.ids[i]); + if (idqinst) + for (i = 0; i < sf.nfiles; i++) + queue_push(idqinst, sf.ids[i]); solv_free(sf.ids); for (i = 0; i < sf.nfiles; i++) { @@ -1141,6 +1292,9 @@ pool_addfileprovides_ids(Pool *pool, Repo *installed, Id **idp) #endif if (installed) pool_addfileprovides_search(pool, &cbd, &isf, installed); + if (installed && idqinst) + for (i = 0; i < isf.nfiles; i++) + queue_pushunique(idqinst, isf.ids[i]); solv_free(isf.ids); for (i = 0; i < isf.nfiles; i++) { @@ -1158,7 +1312,7 @@ pool_addfileprovides_ids(Pool *pool, Repo *installed, Id **idp) void pool_addfileprovides(Pool *pool) { - pool_addfileprovides_ids(pool, pool->installed, 0); + pool_addfileprovides_queue(pool, 0, 0); } void @@ -1201,7 +1355,7 @@ pool_set_languages(Pool *pool, const char **languages, int nlanguages) return; pool->languages = solv_calloc(nlanguages, sizeof(const char **)); for (i = 0; i < pool->nlanguages; i++) - pool->languages[i] = strdup(languages[i]); + pool->languages[i] = solv_strdup(languages[i]); } Id @@ -1211,7 +1365,7 @@ pool_id2langid(Pool *pool, Id id, const char *lang, int create) char buf[256], *p; int l; - if (!lang) + if (!lang || !*lang) return id; n = pool_id2str(pool, id); l = strlen(n) + strlen(lang) + 2; @@ -1618,7 +1772,7 @@ pool_calc_installsizechange(Pool *pool, Map *installedmap) continue; if (!MAPTST(installedmap, sp)) continue; - change += solvable_lookup_num(s, SOLVABLE_INSTALLSIZE, 0); + change += solvable_lookup_sizek(s, SOLVABLE_INSTALLSIZE, 0); } if (oldinstalled) { @@ -1626,7 +1780,7 @@ pool_calc_installsizechange(Pool *pool, Map *installedmap) { if (MAPTST(installedmap, sp)) continue; - change -= solvable_lookup_num(s, SOLVABLE_INSTALLSIZE, 0); + change -= solvable_lookup_sizek(s, SOLVABLE_INSTALLSIZE, 0); } } return change; @@ -1870,12 +2024,12 @@ pool_lookup_id(Pool *pool, Id entry, Id keyname) return solvable_lookup_id(pool->solvables + entry, keyname); } -unsigned int -pool_lookup_num(Pool *pool, Id entry, Id keyname, unsigned int notfound) +unsigned long long +pool_lookup_num(Pool *pool, Id entry, Id keyname, unsigned long long notfound) { if (entry == SOLVID_POS && pool->pos.repo) { - unsigned int value; + unsigned long long value; if (repodata_lookup_num(pool->pos.repo->repodata + pool->pos.repodataid, SOLVID_POS, keyname, &value)) return value; return notfound; @@ -1918,6 +2072,21 @@ pool_lookup_checksum(Pool *pool, Id entry, Id keyname, Id *typep) return solvable_lookup_checksum(pool->solvables + entry, keyname, typep); } +const char * +pool_lookup_deltalocation(Pool *pool, Id entry, unsigned int *medianrp) +{ + const char *loc; + if (medianrp) + *medianrp = 0; + if (entry != SOLVID_POS) + return 0; + loc = pool_lookup_str(pool, entry, DELTA_LOCATION_DIR); + loc = pool_tmpjoin(pool, loc, loc ? "/" : 0, pool_lookup_str(pool, entry, DELTA_LOCATION_NAME)); + loc = pool_tmpappend(pool, loc, "-", pool_lookup_str(pool, entry, DELTA_LOCATION_EVR)); + loc = pool_tmpappend(pool, loc, ".", pool_lookup_str(pool, entry, DELTA_LOCATION_SUFFIX)); + return loc; +} + void pool_add_fileconflicts_deps(Pool *pool, Queue *conflicts) { @@ -1950,4 +2119,37 @@ pool_add_fileconflicts_deps(Pool *pool, Queue *conflicts) pool_freeidhashes(pool); } +char * +pool_prepend_rootdir(Pool *pool, const char *path) +{ + if (!path) + return 0; + if (!pool->rootdir) + return solv_strdup(path); + return solv_dupjoin(pool->rootdir, "/", *path == '/' ? path + 1 : path); +} + +const char * +pool_prepend_rootdir_tmp(Pool *pool, const char *path) +{ + if (!path) + return 0; + if (!pool->rootdir) + return path; + return pool_tmpjoin(pool, pool->rootdir, "/", *path == '/' ? path + 1 : path); +} + +void +pool_set_rootdir(Pool *pool, const char *rootdir) +{ + solv_free(pool->rootdir); + pool->rootdir = solv_strdup(rootdir); +} + +const char * +pool_get_rootdir(Pool *pool) +{ + return pool->rootdir; +} + /* EOF */