/*
* pool.c
- *
+ *
* The pool contains information about solvables
* stored optimized for memory consumption and fast retrieval.
*/
#define SOLVABLE_BLOCK 255
+#undef LIBSOLV_KNOWNID_H
#define KNOWNID_INITIALIZE
#include "knownid.h"
#undef KNOWNID_INITIALIZE
int i;
pool_freewhatprovides(pool);
- for (i = 1; i < pool->nrepos; i++)
+ 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;
+ 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);
}
/*
* pool_createwhatprovides()
- *
+ *
* create hashes over pool of solvables to ease provide lookups
- *
+ *
*/
void
pool_createwhatprovides(Pool *pool)
/*
* pool_queuetowhatprovides - add queue contents to whatprovidesdata
- *
+ *
* used for whatprovides, jobs, learnt rules, selections
* input: q: queue of Ids
* returns: Offset into whatprovidesdata
if (!pool_match_nevr(pool, s, name))
return 0;
return pool_match_nevr(pool, s, evr);
+ case REL_MULTIARCH:
+ if (evr != ARCH_ANY)
+ return 0;
+ /* XXX : need to check for Multi-Arch: allowed! */
+ return pool_match_nevr(pool, s, name);
default:
return 0;
}
/*
* addstdproviders
- *
+ *
* lazy populating of the whatprovides array, non relation case
*/
static Id
/*
* addrelproviders
- *
+ *
* add packages fulfilling the relation to whatprovides array
- *
+ *
+ * some words about REL_AND and REL_IF: we assume the best case
+ * here, so that you get a "potential" result if you ask for a match.
+ * E.g. if you ask for "whatrequires A" and package X contains
+ * "Requires: A & B", you'll get "X" as an answer.
*/
Id
pool_addrelproviders(Pool *pool, Id d)
switch (flags)
{
- case REL_AND:
case REL_WITH:
wp = pool_whatprovides(pool, name);
pp2 = pool_whatprovides_ptr(pool, evr);
wp = 0;
}
break;
+
+ case REL_AND:
case REL_OR:
wp = pool_whatprovides(pool, name);
- pp = pool->whatprovidesdata + wp;
- if (!*pp)
+ if (!pool->whatprovidesdata[wp])
wp = pool_whatprovides(pool, evr);
else
{
- int cnt;
- while ((p = *pp++) != 0)
- queue_push(&plist, p);
- cnt = plist.count;
- pp = pool_whatprovides_ptr(pool, evr);
- while ((p = *pp++) != 0)
- queue_pushunique(&plist, p);
- if (plist.count != cnt)
+ /* sorted merge */
+ pp2 = pool_whatprovides_ptr(pool, evr);
+ pp = pool->whatprovidesdata + wp;
+ while (*pp && *pp2)
+ {
+ if (*pp < *pp2)
+ queue_push(&plist, *pp++);
+ else
+ {
+ if (*pp == *pp2)
+ pp++;
+ queue_push(&plist, *pp2++);
+ }
+ }
+ while (*pp)
+ queue_push(&plist, *pp++);
+ while (*pp2)
+ queue_push(&plist, *pp2++);
+ /* if the number of elements did not change, we can reuse wp */
+ if (pp - (pool->whatprovidesdata + wp) != plist.count)
wp = 0;
}
break;
+
+ case REL_COND:
+ /* assume the condition is true */
+ wp = pool_whatprovides(pool, name);
+ break;
+
case REL_NAMESPACE:
if (name == NAMESPACE_OTHERPROVIDERS)
{
wp = 0;
}
break;
+ case REL_MULTIARCH:
+ if (evr != ARCH_ANY)
+ break;
+ /* XXX : need to check for Multi-Arch: allowed! */
+ wp = pool_whatprovides(pool, name);
+ break;
case REL_KIND:
/* package kind filtering */
if (!name)
struct searchfiles {
Id *ids;
- char **dirs;
- char **names;
int nfiles;
Map seen;
};
pool_addfileprovides_dep(Pool *pool, Id *ida, struct searchfiles *sf, struct searchfiles *isf)
{
Id dep, sid;
- const char *s, *sr;
+ const char *s;
struct searchfiles *csf;
while ((dep = *ida++) != 0)
if (csf != isf && pool->addedfileprovides == 1 && !repodata_filelistfilter_matches(0, s))
continue; /* skip non-standard locations csf == isf: installed case */
csf->ids = solv_extend(csf->ids, csf->nfiles, 1, sizeof(Id), SEARCHFILES_BLOCK);
- csf->dirs = solv_extend(csf->dirs, csf->nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK);
- 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] = solv_strdup(sr + 1);
- csf->dirs[csf->nfiles] = solv_malloc(sr - s + 1);
- if (sr != s)
- strncpy(csf->dirs[csf->nfiles], s, sr - s);
- csf->dirs[csf->nfiles][sr - s] = 0;
- csf->nfiles++;
+ csf->ids[csf->nfiles++] = dep;
}
}
if (!cbd->useddirs.size)
{
map_init(&cbd->useddirs, data->dirpool.ndirs + 1);
+ if (!cbd->dirs)
+ {
+ cbd->dirs = solv_malloc2(cbd->nfiles, sizeof(char *));
+ cbd->names = solv_malloc2(cbd->nfiles, sizeof(char *));
+ for (i = 0; i < cbd->nfiles; i++)
+ {
+ char *s = solv_strdup(pool_id2str(data->repo->pool, cbd->ids[i]));
+ cbd->dirs[i] = s;
+ s = strrchr(s, '/');
+ *s = 0;
+ cbd->names[i] = s + 1;
+ }
+ }
for (i = 0; i < cbd->nfiles; i++)
{
Id did;
if (value->id >= data->dirpool.ndirs || !MAPTST(&cbd->useddirs, value->id))
return 0;
for (i = 0; i < cbd->nfiles; i++)
- {
- if (cbd->dids[i] != value->id)
- continue;
- if (!strcmp(cbd->names[i], value->str))
- break;
- }
- if (i == cbd->nfiles)
- return 0;
- s->provides = repo_addid_dep(s->repo, s->provides, cbd->ids[i], SOLVABLE_FILEMARKER);
+ if (cbd->dids[i] == value->id && !strcmp(cbd->names[i], value->str))
+ s->provides = repo_addid_dep(s->repo, s->provides, cbd->ids[i], SOLVABLE_FILEMARKER);
return 0;
}
cbd->nfiles = sf->nfiles;
cbd->ids = sf->ids;
- cbd->dirs = sf->dirs;
- cbd->names = sf->names;
+ cbd->dirs = 0;
+ cbd->names = 0;
cbd->dids = solv_realloc2(cbd->dids, sf->nfiles, sizeof(Id));
map_init(&cbd->providedids, pool->ss.nstrings);
map_free(&donemap);
queue_free(&fileprovidesq);
map_free(&cbd->providedids);
+ if (cbd->dirs)
+ {
+ for (i = 0; i < cbd->nfiles; i++)
+ solv_free(cbd->dirs[i]);
+ cbd->dirs = solv_free(cbd->dirs);
+ cbd->names = solv_free(cbd->names);
+ }
}
void
for (i = 0; i < sf.nfiles; i++)
queue_push(idqinst, sf.ids[i]);
solv_free(sf.ids);
- for (i = 0; i < sf.nfiles; i++)
- {
- solv_free(sf.dirs[i]);
- solv_free(sf.names[i]);
- }
- solv_free(sf.dirs);
- solv_free(sf.names);
}
if (isf.nfiles)
{
for (i = 0; i < isf.nfiles; i++)
queue_pushunique(idqinst, isf.ids[i]);
solv_free(isf.ids);
- for (i = 0; i < isf.nfiles; i++)
- {
- solv_free(isf.dirs[i]);
- solv_free(isf.names[i]);
- }
- solv_free(isf.dirs);
- solv_free(isf.names);
}
solv_free(cbd.dids);
pool_freewhatprovides(pool); /* as we have added provides */
pool->languagecache = solv_free(pool->languagecache);
pool->languagecacheother = 0;
- if (pool->nlanguages)
- {
- for (i = 0; i < pool->nlanguages; i++)
- free((char *)pool->languages[i]);
- free(pool->languages);
- }
+ for (i = 0; i < pool->nlanguages; i++)
+ free((char *)pool->languages[i]);
+ pool->languages = solv_free(pool->languages);
pool->nlanguages = nlanguages;
if (!nlanguages)
return;
#define MPTREE_BLOCK 15
-void
-pool_calc_duchanges(Pool *pool, Map *installedmap, DUChanges *mps, int nmps)
+static struct mptree *
+create_mptree(DUChanges *mps, int nmps)
{
- char *p;
- const char *path, *compstr;
- struct mptree *mptree;
int i, nmptree;
+ struct mptree *mptree;
int pos, compl;
int mp;
- struct ducbdata cbd;
- Solvable *s;
- Id sp;
- Map ignoredu;
- Repo *oldinstalled = pool->installed;
-
- memset(&ignoredu, 0, sizeof(ignoredu));
- cbd.mps = mps;
- cbd.addsub = 0;
- cbd.dirmap = 0;
- cbd.nmap = 0;
- cbd.olddata = 0;
+ const char *p, *path, *compstr;
mptree = solv_extend_resize(0, 1, sizeof(struct mptree), MPTREE_BLOCK);
mptree[0].compl = 0;
mptree[0].mountpoint = -1;
nmptree = 1;
-
+
/* create component tree */
for (mp = 0; mp < nmps; mp++)
{
}
#endif
+ return mptree;
+}
+
+void
+pool_calc_duchanges(Pool *pool, Map *installedmap, DUChanges *mps, int nmps)
+{
+ struct mptree *mptree;
+ struct ducbdata cbd;
+ Solvable *s;
+ int sp;
+ Map ignoredu;
+ Repo *oldinstalled = pool->installed;
+
+ map_init(&ignoredu, 0);
+ mptree = create_mptree(mps, nmps);
+
+ cbd.mps = mps;
+ cbd.dirmap = 0;
+ cbd.nmap = 0;
+ cbd.olddata = 0;
cbd.mptree = mptree;
cbd.addsub = 1;
for (sp = 1, s = pool->solvables + sp; sp < pool->nsolvables; sp++, s++)
{
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);
+ if (!ignoredu.size)
+ map_grow(&ignoredu, oldinstalled->end - oldinstalled->start);
if (s->obsoletes)
{
Id obs, *obsp = s->repo->idarraydata + s->obsoletes;
repo_search(oldinstalled, sp, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
}
}
- if (ignoredu.map)
- map_free(&ignoredu);
+ map_free(&ignoredu);
solv_free(cbd.dirmap);
solv_free(mptree);
}
* 8: interesting (only true if installed)
* 16: undecided
*/
-
+
static inline Id dep2name(Pool *pool, Id dep)
{
while (ISRELDEP(dep))
{
- Reldep *rd = rd = GETRELDEP(pool, dep);
+ Reldep *rd = GETRELDEP(pool, dep);
dep = rd->name;
}
return dep;
}
-static int providedbyinstalled_multiversion(Pool *pool, unsigned char *map, Id n, Id con)
+static int providedbyinstalled_multiversion(Pool *pool, unsigned char *map, Id n, Id con)
{
Id p, pp;
- Solvable *sn = pool->solvables + n;
+ Solvable *sn = pool->solvables + n;
FOR_PROVIDES(p, pp, sn->name)
- {
- Solvable *s = pool->solvables + p;
+ {
+ Solvable *s = pool->solvables + p;
if (s->name != sn->name || s->arch != sn->arch)
continue;
if ((map[p] & 9) != 9)