X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fpool.c;h=4b6ab433f90b710194c7e4cd959148c8f68bdf58;hb=eef58960087e9d7b347e77629b0da03b656b8377;hp=ebc801632d26d075c04d04d1b931c0dc8d109c75;hpb=1a04759b6b594876286af072f25b28d3b0db4ed6;p=platform%2Fupstream%2Flibsolv.git diff --git a/src/pool.c b/src/pool.c index ebc8016..4b6ab43 100644 --- a/src/pool.c +++ b/src/pool.c @@ -54,27 +54,34 @@ pool_create(void) 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; } @@ -90,6 +97,7 @@ pool_free(Pool *pool) pool_freeidhashes(pool); pool_freeallrepos(pool, 1); solv_free(pool->id2arch); + solv_free(pool->id2color); solv_free(pool->solvables); stringpool_free(&pool->ss); solv_free(pool->rels); @@ -101,6 +109,8 @@ 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); } @@ -111,7 +121,8 @@ pool_freeallrepos(Pool *pool, int reuseids) pool_freewhatprovides(pool); for (i = 1; i < pool->nrepos; i++) - repo_freedata(pool->repos[i]); + if (pool->repos[i]) + repo_freedata(pool->repos[i]); pool->repos = solv_free(pool->repos); pool->nrepos = 0; pool->urepos = 0; @@ -124,9 +135,75 @@ 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) { @@ -181,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) @@ -204,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; @@ -213,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) { @@ -300,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); @@ -452,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 @@ -474,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)) @@ -492,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; } @@ -512,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; } @@ -648,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); @@ -724,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 */ @@ -788,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) @@ -944,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; @@ -1085,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++) { @@ -1125,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 @@ -1134,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++) { @@ -1158,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++) { @@ -1175,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 @@ -1228,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; @@ -1635,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) { @@ -1643,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; @@ -1887,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; @@ -1935,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) { @@ -1967,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 */