From: Michael Schroeder Date: Fri, 11 Jan 2008 20:42:25 +0000 (+0000) Subject: - fix support for splitprovides X-Git-Tag: BASE-SuSE-Code-12_1-Branch~1016 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cbb469ae23bc51d0e89ef96db63bf5c481403f9b;p=platform%2Fupstream%2Flibsolv.git - fix support for splitprovides - add some unfinished code for DU queries --- diff --git a/src/pool.c b/src/pool.c index 75a0a51..c2eab07 100644 --- a/src/pool.c +++ b/src/pool.c @@ -54,6 +54,7 @@ static const char *initpool_data[] = { "solvable:filemarker", "namespace:installed", "namespace:modalias", + "namespace:splitprovides", "system:system", "src", "nosrc", @@ -632,12 +633,13 @@ pool_setdebuglevel(Pool *pool, int level) struct searchfiles { const char **files; int nfiles; + Map seen; }; #define SEARCHFILES_BLOCK 127 static void -pool_addfileprovides_dep(Pool *pool, Id *ida, Map *seen, struct searchfiles *sf) +pool_addfileprovides_dep(Pool *pool, Id *ida, struct searchfiles *sf, struct searchfiles *isf) { Id dep, sid; const char *s; @@ -648,21 +650,27 @@ pool_addfileprovides_dep(Pool *pool, Id *ida, Map *seen, struct searchfiles *sf) { Reldep *rd; sid = pool->ss.nstrings + GETRELID(dep); - if (MAPTST(seen, sid)) + if (MAPTST(&sf->seen, sid)) { dep = 0; break; } - MAPSET(seen, sid); + MAPSET(&sf->seen, sid); rd = GETRELDEP(pool, dep); if (rd->flags < 8) dep = rd->name; else if (rd->flags == REL_NAMESPACE) { - if (rd->name == NAMESPACE_INSTALLED) + if (isf && (rd->name == NAMESPACE_INSTALLED || rd->name == NAMESPACE_SPLITPROVIDES)) { - dep = 0; /* for now */ - break; + sf = isf; + isf = 0; + if (MAPTST(&sf->seen, sid)) + { + dep = 0; + break; + } + MAPSET(&sf->seen, sid); } dep = rd->evr; } @@ -671,15 +679,15 @@ pool_addfileprovides_dep(Pool *pool, Id *ida, Map *seen, struct searchfiles *sf) Id ids[2]; ids[0] = rd->name; ids[1] = 0; - pool_addfileprovides_dep(pool, ids, seen, sf); + pool_addfileprovides_dep(pool, ids, sf, isf); dep = rd->evr; } } if (!dep) continue; - if (MAPTST(seen, dep)) + if (MAPTST(&sf->seen, dep)) continue; - MAPSET(seen, dep); + MAPSET(&sf->seen, dep); s = id2str(pool, dep); if (*s != '/') continue; @@ -704,16 +712,17 @@ addfileprovides_cb(void *data, Solvable *s, Id key, const char *str) #endif void -pool_addfileprovides(Pool *pool) +pool_addfileprovides(Pool *pool, Repo *installed) { Solvable *s; Repo *repo; - Map seen; - struct searchfiles sf; + struct searchfiles sf, isf; int i; - map_init(&seen, pool->ss.nstrings + pool->nrels); 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); for (i = 1, s = pool->solvables + i; i < pool->nsolvables; i++, s++) { @@ -721,38 +730,271 @@ pool_addfileprovides(Pool *pool) if (!repo) continue; if (s->obsoletes) - pool_addfileprovides_dep(pool, repo->idarraydata + s->obsoletes, &seen, &sf); + pool_addfileprovides_dep(pool, repo->idarraydata + s->obsoletes, &sf, &isf); if (s->conflicts) - pool_addfileprovides_dep(pool, repo->idarraydata + s->conflicts, &seen, &sf); + pool_addfileprovides_dep(pool, repo->idarraydata + s->conflicts, &sf, &isf); if (s->requires) - pool_addfileprovides_dep(pool, repo->idarraydata + s->requires, &seen, &sf); + pool_addfileprovides_dep(pool, repo->idarraydata + s->requires, &sf, &isf); if (s->recommends) - pool_addfileprovides_dep(pool, repo->idarraydata + s->recommends, &seen, &sf); + pool_addfileprovides_dep(pool, repo->idarraydata + s->recommends, &sf, &isf); if (s->suggests) - pool_addfileprovides_dep(pool, repo->idarraydata + s->suggests, &seen, &sf); + pool_addfileprovides_dep(pool, repo->idarraydata + s->suggests, &sf, &isf); if (s->supplements) - pool_addfileprovides_dep(pool, repo->idarraydata + s->supplements, &seen, &sf); + pool_addfileprovides_dep(pool, repo->idarraydata + s->supplements, &sf, &isf); if (s->enhances) - pool_addfileprovides_dep(pool, repo->idarraydata + s->enhances, &seen, &sf); + pool_addfileprovides_dep(pool, repo->idarraydata + s->enhances, &sf, &isf); if (s->freshens) - pool_addfileprovides_dep(pool, repo->idarraydata + s->freshens, &seen, &sf); + pool_addfileprovides_dep(pool, repo->idarraydata + s->freshens, &sf, &isf); } - map_free(&seen); + map_free(&sf.seen); + map_free(&isf.seen); POOL_DEBUG(SAT_DEBUG_STATS, "found %d file dependencies\n", sf.nfiles); - if (!sf.nfiles) - return; + POOL_DEBUG(SAT_DEBUG_STATS, "found %d installed file dependencies\n", isf.nfiles); + if (sf.nfiles) + { +#if 0 + for (i = 0; i < sf.nfiles; i++) + POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in filelist\n", sf.files[i]); +#endif + if ((sf.nfiles & SEARCHFILES_BLOCK) == 0) + sf.files = sat_realloc2(sf.files, sf.nfiles + (SEARCHFILES_BLOCK + 1), sizeof(const char *)); + sf.files[sf.nfiles++] = 0; +#if 0 + pool_search(0, SOLVABLE_FILELIST, (const char *)sf.files, SEARCH_STRING|SEARCH_MULTIPLE, addfileprovides_cb, 0); +#endif + sat_free(sf.files); + } + if (isf.nfiles && installed) + { #if 0 - for (i = 0; i < sf.nfiles; i++) - POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in filelist\n", sf.files[i]); + for (i = 0; i < isf.nfiles; i++) + POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in installed filelist\n", isf.files[i]); #endif - if ((sf.nfiles & SEARCHFILES_BLOCK) == 0) - sf.files = sat_realloc2(sf.files, sf.nfiles + (SEARCHFILES_BLOCK + 1), sizeof(const char *)); - sf.files[sf.nfiles++] = 0; + if ((isf.nfiles & SEARCHFILES_BLOCK) == 0) + isf.files = sat_realloc2(isf.files, isf.nfiles + (SEARCHFILES_BLOCK + 1), sizeof(const char *)); + isf.files[isf.nfiles++] = 0; #if 0 - pool_search(0, SOLVABLE_FILELIST, (const char *)sf.files, SEARCH_STRING|SEARCH_MULTIPLE, addfileprovides_cb, 0); + repo_search(installed, 0, SOLVABLE_FILELIST, (const char *)isf.files, SEARCH_STRING|SEARCH_MULTIPLE, addfileprovides_cb, 0); #endif - sat_free(sf.files); + sat_free(isf.files); + } pool_freewhatprovides(pool); /* as we have added provides */ } +#if 0 + +struct mountpoint { + const char *path; + int kbytes; + int files; +}; + +struct mptree { + Id sibling; + Id child; + const char *comp; + int compl; + Id mountpoint; +}; + +struct cbdata { + struct mountpoint *mps; + Id *dirmap; + int nmap; +}; + +static int +pool_fill_DU_add_cb(void *data, Solvable *s, Id key, const char *str) +{ + struct cbdata *cbdata = data; + Id mp, dirnum, kbytes, files; + + dp = data_read_id(dp, &dirnum); + dp = data_read_id(dp, &kbytes); + data_read_id(dp, &files); + if (dirnum < 0 || dirnum > cbdata->nmap) + return 0; + mp = cbdata->dirmap[dirnum]; + if (mp >= 0) + { + cbdata->mps[mp].kbytes += kbytes; + cbdata->mps[mp].files += files; + } + return 0; +} + +static int +pool_fill_DU_sub_cb(void *data, Solvable *s, Id key, const char *str) +{ + struct cbdata *cbdata = data; + Id mp, dirnum, kbytes, files; + + dp = data_read_id(dp, &dirnum); + dp = data_read_id(dp, &kbytes); + data_read_id(dp, &files); + if (dirnum < 0 || dirnum > cbdata->nmap) + return 0; + mp = cbdata->dirmap[dirnum]; + if (mp >= 0) + { + cbdata->mps[mp].kbytes -= kbytes; + cbdata->mps[mp].files -= files; + } + return 0; +} + +static void +propagate_mountpoints(struct mptree *mptree, int pos, Id mountpoint) +{ + int i; + if (mptree[pos].mountpoint == -1) + mptree[pos].mountpoint = mountpoint; + else + mountpoint = mptree[pos].mountpoint; + for (i = mptree[pos].child; i; i = mptree[i].sibling) + propagate_mountpoints(mptree, i, mountpoint); +} + +void +pool_fill_DU(Pool *pool, struct mountpoint *mps, int nmps) +{ + char *path, *p; + Id *dirmap; + struct mptree *mptree; + int nmptree; + int pos; + int mp; + + struct matchdata md; + struct cbdata cbdata; + + memset(&md, 0, sizeof(md)); + md.pool = 0; + md.matchstr = 0; + md.flags = 0; + md.callback = 0; + md.callback_data = &cbdata + + cbdata.mps = mps; + cbdata.dirmap = 0; + cbdata.nmap = 0; + + mptree = sat_malloc2(16, sizeof(mptree)); + + /* our root node */ + mptree[0].sibling = 0; + mptree[0].child = 0; + mptree[0].comp = 0; + mptree[0].compl = 0; + mptree[0].mountpoint = -1; + nmptree = 1; + + /* create component tree */ + for (mp = 0; mp < nmps; mp++) + { + pos = 0; + path = mps[mp].path; + while(*path == '/') + path++; + while (*path) + { + if ((p = strchr('/', path)) == 0) + { + comp = path; + compl = strlen(comp); + path += compl; + } + else + { + comp = path; + compl = p - path; + path = p + 1; + while(*path == '/') + path++; + } + for (i = mptree[pos].child; i; i = mptree[i].sibling) + if (mptree[i].compl == compl && !strncmp(mptree[i].comp, comp, compl)) + break; + if (!i) + { + /* create new node */ + if ((nmptree & 15) == 0) + mptree = sat_realloc2(mptree, nmptree + 16, sizeof(mptree)); + i = nmptree++; + mptree[i].sibling = mptree[pos].child; + mptree[i].child = 0; + mptree[i].comp = comp; + mptree[i].compl = compl; + mptree[i].mountpoint = -1; + mptree[pos].child = i; + } + pos = i; + } + mptree[pos].mountpoint = mp; + } + propagate_mountpoints(mptree, 0, mptree[0].mountpoint); + + for_all_repos + { + for_all_repodatas_containing_DU + { + dirmap = xcalloc2(data->ndirs, sizeof(Id)); + dirnum = 0; + for (;;) + { + parent = readid(); + mp = parent ? dirmap[parent] : 0; + while (id = readid()) + { + if (mp < 0) + { + /* unconnected */ + dirmap[dirnum++] = mp; + continue; + } + if (!mptree[mp].child) + { + dirmap[dirnum++] = -mp; + continue; + } + comp = id2str(pool, id); + compl = strlen(comp); + for (i = mptree[mp].child; i; i = mptree[i].sibling) + if (mptree[i].compl == compl && !strncmp(mptree[i].comp, comp, compl)) + break; + dirmap[dirnum++] = i ? i : -mp; + } + } + for (i = 0; i < dirnum; i++) + { + mp = dirmap[i]; + dirmap[i] = mptree[mp > 0 ? mp : -mp].mountpoint; + } + cbdata.nmap = dirnum; + cbdata.dirmap = dirmap; + + md.callback = pool_fill_DU_add_cb; + for_solvables_to_be_installed() + { + if (p < data->start || p >= data->end) + continue; + repodata_search(data, p - data->start, SOLVABLE_DUDATA, &md); + } + md.callback = pool_fill_DU_sub_cb; + for_solvables_to_be_erased() + { + if (p < data->start || p >= data->end) + continue; + repodata_search(data, p - data->start, SOLVABLE_DUDATA, &md); + } + + cbdata.dirmap = 0; + cbdata.nmap = 0; + sat_free(dirmap); + } + } +} + +#endif + // EOF diff --git a/src/pool.h b/src/pool.h index 01beb33..1e0b58a 100644 --- a/src/pool.h +++ b/src/pool.h @@ -46,15 +46,16 @@ extern "C" { #define SOLVABLE_FILEMARKER 17 // normal provides before this, generated file provides after this #define NAMESPACE_INSTALLED 18 #define NAMESPACE_MODALIAS 19 -#define SYSTEM_SYSTEM 20 -#define ARCH_SRC 21 -#define ARCH_NOSRC 22 -#define ARCH_NOARCH 23 -#define REPODATA_EXTERNAL 24 -#define REPODATA_KEYS 25 -#define REPODATA_LOCATION 26 +#define NAMESPACE_SPLITPROVIDES 20 +#define SYSTEM_SYSTEM 21 +#define ARCH_SRC 22 +#define ARCH_NOSRC 23 +#define ARCH_NOARCH 24 +#define REPODATA_EXTERNAL 25 +#define REPODATA_KEYS 26 +#define REPODATA_LOCATION 27 -#define ID_NUM_INTERNAL 27 +#define ID_NUM_INTERNAL 28 /* well known solvable */ @@ -207,7 +208,7 @@ extern const char *solvable2str(Pool *pool, Solvable *s); * Prepares a pool for solving */ extern void pool_createwhatprovides(Pool *pool); -extern void pool_addfileprovides(Pool *pool); +extern void pool_addfileprovides(Pool *pool, struct _Repo *installed); extern void pool_freewhatprovides(Pool *pool); extern Id pool_queuetowhatprovides(Pool *pool, Queue *q); diff --git a/src/repo.c b/src/repo.c index 094947a..a18ae6c 100644 --- a/src/repo.c +++ b/src/repo.c @@ -318,7 +318,7 @@ Offset repo_fix_legacy(Repo *repo, Offset provides, Offset supplements) { Pool *pool = repo->pool; - Id id, idp, idl, idns; + Id id, idp, idl; char buf[1024], *p, *dep; int i; @@ -381,10 +381,9 @@ repo_fix_legacy(Repo *repo, Offset provides, Offset supplements) p = buf + (p - dep); *p++ = 0; idp = str2id(pool, buf, 1); - idns = str2id(pool, "namespace:installed", 1); id = str2id(pool, p, 1); - id = rel2id(pool, idns, id, REL_NAMESPACE, 1); - id = rel2id(pool, idp, id, REL_AND, 1); + id = rel2id(pool, idp, id, REL_WITH, 1); + id = rel2id(pool, NAMESPACE_SPLITPROVIDES, id, REL_NAMESPACE, 1); supplements = repo_addid_dep(repo, supplements, id, 0); } } @@ -403,14 +402,13 @@ repo_fix_legacy(Repo *repo, Offset provides, Offset supplements) { strcpy(buf, dep); p = strchr(buf + 9, ':'); - idns = str2id(pool, "namespace:modalias", 1); if (p && p != buf + 9 && strchr(p + 1, ':')) { *p++ = 0; idp = str2id(pool, buf + 9, 1); p[strlen(p) - 1] = 0; id = str2id(pool, p, 1); - id = rel2id(pool, idns, id, REL_NAMESPACE, 1); + id = rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1); id = rel2id(pool, idp, id, REL_AND, 1); } else @@ -418,7 +416,7 @@ repo_fix_legacy(Repo *repo, Offset provides, Offset supplements) p = buf + 9; p[strlen(p) - 1] = 0; id = str2id(pool, p, 1); - id = rel2id(pool, idns, id, REL_NAMESPACE, 1); + id = rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1); } if (id) repo->idarraydata[i] = id; @@ -738,6 +736,30 @@ repo_search_md(Repo *repo, Id p, Id key, struct matchdata *md) md->stop = 0; if (!p) { +#if 0 + switch(key) + { + case 0: + case SOLVABLE_NAME: + case SOLVABLE_ARCH: + case SOLVABLE_EVR: + case SOLVABLE_VENDOR: + case SOLVABLE_PROVIDES: + case SOLVABLE_OBSOLETES: + case SOLVABLE_CONFLICTS: + case SOLVABLE_REQUIRES: + case SOLVABLE_RECOMMENDS: + case SOLVABLE_SUPPLEMENTS: + case SOLVABLE_SUGGESTS: + case SOLVABLE_ENHANCES: + case SOLVABLE_FRESHENS: + break; + default: + for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) + repodata_search(data, -1, key, md); + return; + } +#endif for (p = repo->start, s = repo->pool->solvables + p; p < repo->end; p++, s++) { if (s->repo == repo) diff --git a/src/solver.c b/src/solver.c index 7b31c03..69057c3 100644 --- a/src/solver.c +++ b/src/solver.c @@ -29,10 +29,32 @@ int +solver_splitprovides(Solver *solv, Id dep) +{ + Pool *pool = solv->pool; + Id p, *pp; + Reldep *rd; + Solvable *s; + + if (!solv->dosplitprovides || !solv->installed) + return 0; + if (!ISRELDEP(dep)) + return 0; + rd = GETRELDEP(pool, dep); + if (rd->flags != REL_WITH) + return 0; + FOR_PROVIDES(p, pp, dep) + { + s = pool->solvables + p; + if (s->repo == solv->installed && s->name == rd->name) + return 1; + } + return 0; +} + +int solver_dep_installed(Solver *solv, Id dep) { - /* disable for now, splitprovides don't work anyway and it breaks - a testcase */ #if 0 Pool *pool = solv->pool; Id p, *pp; @@ -75,6 +97,8 @@ dep_possible(Solver *solv, Id dep, Map *m) return 0; return dep_possible(solv, rd->evr, m); } + if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES) + return solver_splitprovides(solv, rd->evr); if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_INSTALLED) return solver_dep_installed(solv, rd->evr); } diff --git a/src/solver.h b/src/solver.h index 98c476b..0ac879f 100644 --- a/src/solver.h +++ b/src/solver.h @@ -58,6 +58,7 @@ typedef struct solver { int updatesystem; /* distupgrade */ int allowvirtualconflicts; /* false: conflicts on package name, true: conflicts on package provides */ int noupdateprovide; /* true: update packages needs not to provide old package */ + int dosplitprovides; /* true: consider legacy split provides */ Rule *rules; /* all rules */ Id nrules; /* index of the last rule */ @@ -140,6 +141,7 @@ extern Solver *solver_create(Pool *pool, Repo *installed); extern void solver_free(Solver *solv); extern void solver_solve(Solver *solv, Queue *job); extern int solver_dep_installed(Solver *solv, Id dep); +extern int solver_splitprovides(Solver *solv, Id dep); extern Id solver_next_problem(Solver *solv, Id problem); extern Id solver_next_solution(Solver *solv, Id problem, Id solution); @@ -169,6 +171,8 @@ solver_dep_fulfilled(Solver *solv, Id dep) return 0; return solver_dep_fulfilled(solv, rd->evr); } + if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES) + return solver_splitprovides(solv, rd->evr); if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_INSTALLED) return solver_dep_installed(solv, rd->evr); }