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->disttype = DISTTYPE_DEB;
-#endif
#ifdef RPM5
pool->forbidselfconflicts = 1;
pool->obsoleteusesprovides = 1;
pool->implicitobsoleteusesprovides = 1;
+ pool->havedistepoch = 1;
#endif
return 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);
}
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
return pool->obsoleteusescolors;
case POOL_FLAG_NOINSTALLEDOBSOLETES:
return pool->noinstalledobsoletes;
+ case POOL_FLAG_HAVEDISTEPOCH:
+ return pool->havedistepoch;
default:
break;
}
case POOL_FLAG_NOINSTALLEDOBSOLETES:
pool->noinstalledobsoletes = value;
break;
+ case POOL_FLAG_HAVEDISTEPOCH:
+ pool->havedistepoch = value;
+ break;
default:
break;
}
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)
static void
pool_shrink_whatprovides(Pool *pool)
{
- Id i, id;
+ Id i, n, id;
Id *sorted;
Id lastid, *last, *dp, *lp;
Offset o;
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)
{
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);
#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
{
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))
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;
}
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;
}
* 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);
pidp = s->repo->idarraydata + s->provides;
while ((pid = *pidp++) != 0)
{
- if (pid == name)
+ if (!ISRELDEP(pid))
{
+ if (pid != name)
+ continue; /* wrong provides name */
if (pool->disttype == DISTTYPE_DEB)
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 */
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)
}
void
-pool_addfileprovides_queue(Pool *pool, Queue *idq)
+pool_addfileprovides_queue(Pool *pool, Queue *idq, Queue *idqinst)
{
Solvable *s;
Repo *installed, *repo;
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++)
{
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++)
{
#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++)
{
void
pool_addfileprovides(Pool *pool)
{
- pool_addfileprovides_queue(pool, 0);
+ pool_addfileprovides_queue(pool, 0, 0);
}
void
continue;
if (!MAPTST(installedmap, sp))
continue;
- change += solvable_lookup_num(s, SOLVABLE_INSTALLSIZE, 0);
+ change += solvable_lookup_sizek(s, SOLVABLE_INSTALLSIZE, 0);
}
if (oldinstalled)
{
{
if (MAPTST(installedmap, sp))
continue;
- change -= solvable_lookup_num(s, SOLVABLE_INSTALLSIZE, 0);
+ change -= solvable_lookup_sizek(s, SOLVABLE_INSTALLSIZE, 0);
}
}
return change;
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;
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)
{
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 */