summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dataiterator.h11
-rw-r--r--src/knownid.h24
-rw-r--r--src/libsolv.ver2
-rw-r--r--src/policy.c24
-rw-r--r--src/pool.c47
-rw-r--r--src/pool.h6
-rw-r--r--src/repo.h13
-rw-r--r--src/repo_write.c2
-rw-r--r--src/repodata.c126
-rw-r--r--src/repodata.h1
-rw-r--r--src/repopack.h4
-rw-r--r--src/rules.c95
-rw-r--r--src/rules.h1
-rw-r--r--src/selection.c32
-rw-r--r--src/solvable.c47
-rw-r--r--src/solver.c171
-rw-r--r--src/solver.h52
17 files changed, 510 insertions, 148 deletions
diff --git a/src/dataiterator.h b/src/dataiterator.h
index 6f8fd32..a77d902 100644
--- a/src/dataiterator.h
+++ b/src/dataiterator.h
@@ -132,6 +132,16 @@ typedef struct _Dataiterator
} parents[3];
int nparents;
+ /* vertical data */
+ unsigned char *vert_ddp;
+ Id vert_off;
+ Id vert_len;
+ Id vert_storestate;
+
+ /* strdup data */
+ char *dupstr;
+ int dupstrn;
+
} Dataiterator;
@@ -165,6 +175,7 @@ void dataiterator_jump_to_repo(Dataiterator *di, struct _Repo *repo);
void dataiterator_entersub(Dataiterator *di);
void dataiterator_clonepos(Dataiterator *di, Dataiterator *from);
void dataiterator_seek(Dataiterator *di, int whence);
+void dataiterator_strdup(Dataiterator *di);
#define DI_SEEK_STAY (1 << 16)
#define DI_SEEK_CHILD 1
diff --git a/src/knownid.h b/src/knownid.h
index ad8b4a4..83b943e 100644
--- a/src/knownid.h
+++ b/src/knownid.h
@@ -58,6 +58,7 @@ KNOWNID(ARCH_SRC, "src"),
KNOWNID(ARCH_NOSRC, "nosrc"),
KNOWNID(ARCH_NOARCH, "noarch"),
KNOWNID(ARCH_ALL, "all"),
+KNOWNID(ARCH_ANY, "any"),
KNOWNID(REPOSITORY_SOLVABLES, "repository:solvables"),
KNOWNID(REPOSITORY_DELTAINFO, "repository:deltainfo"),
@@ -133,6 +134,11 @@ KNOWNID(SOLVABLE_LEADSIGID, "solvable:leadsigid"), /* leadsigid: md5sum over l
KNOWNID(SOLVABLE_PATCHCATEGORY, "solvable:patchcategory"),
KNOWNID(SOLVABLE_HEADEREND, "solvable:headerend"),
+KNOWNID(SOLVABLE_CHANGELOG, "solvable:changelog"),
+KNOWNID(SOLVABLE_CHANGELOG_AUTHOR, "solvable:changelog:author"),
+KNOWNID(SOLVABLE_CHANGELOG_TIME, "solvable:changelog:time"),
+KNOWNID(SOLVABLE_CHANGELOG_TEXT, "solvable:changelog:text"),
+
/* stuff for solvables of type pattern */
KNOWNID(SOLVABLE_CATEGORY, "solvable:category"),
@@ -184,6 +190,10 @@ KNOWNID(SUSETAGS_FILE, "susetags:file"),
KNOWNID(SUSETAGS_FILE_NAME, "susetags:file:name"),
KNOWNID(SUSETAGS_FILE_TYPE, "susetags:file:type"),
KNOWNID(SUSETAGS_FILE_CHECKSUM, "susetags:file:checksum"),
+KNOWNID(SUSETAGS_SHARE_NAME, "susetags:share:name"),
+KNOWNID(SUSETAGS_SHARE_EVR, "susetags:share:evr"),
+KNOWNID(SUSETAGS_SHARE_ARCH, "susetags:share:arch"),
+
/* timestamp then the repository was generated */
KNOWNID(REPOSITORY_TIMESTAMP, "repository:timestamp"),
@@ -200,11 +210,13 @@ KNOWNID(REPOSITORY_UPDATES, "repository:updates"),
KNOWNID(REPOSITORY_DISTROS, "repository:distros"),
KNOWNID(REPOSITORY_PRODUCT_LABEL, "repository:product:label"),
KNOWNID(REPOSITORY_PRODUCT_CPEID, "repository:product:cpeid"),
+KNOWNID(REPOSITORY_REPOID, "repository:repoid"), /* obsolete? */
/* keyword (tags) for this repository */
KNOWNID(REPOSITORY_KEYWORDS, "repository:keywords"),
/* revision of the repository. arbitrary string */
KNOWNID(REPOSITORY_REVISION, "repository:revision"),
+KNOWNID(REPOSITORY_TOOLVERSION, "repository:toolversion"),
KNOWNID(DELTA_PACKAGE_NAME, "delta:pkgname"),
KNOWNID(DELTA_PACKAGE_EVR, "delta:pkgevr"),
@@ -229,23 +241,13 @@ KNOWNID(REPOSITORY_REPOMD_LOCATION, "repository:repomd:location"),
KNOWNID(REPOSITORY_REPOMD_TIMESTAMP, "repository:repomd:timestamp"),
KNOWNID(REPOSITORY_REPOMD_CHECKSUM, "repository:repomd:checksum"),
KNOWNID(REPOSITORY_REPOMD_OPENCHECKSUM, "repository:repomd:openchecksum"),
+KNOWNID(REPOSITORY_REPOMD_SIZE, "repository:repomd:size"),
KNOWNID(PUBKEY_KEYID, "pubkey:keyid"),
KNOWNID(PUBKEY_FINGERPRINT, "pubkey:fingerprint"),
KNOWNID(PUBKEY_EXPIRES, "pubkey:expires"),
KNOWNID(PUBKEY_SIGNATURES, "pubkey:signatures"),
-KNOWNID(REPOSITORY_TOOLVERSION, "repository:toolversion"),
-KNOWNID(REPOSITORY_REPOID, "repository:repoid"),
-
-KNOWNID(SUSETAGS_SHARE_NAME, "susetags:share:name"),
-KNOWNID(SUSETAGS_SHARE_EVR, "susetags:share:evr"),
-KNOWNID(SUSETAGS_SHARE_ARCH, "susetags:share:arch"),
-
-KNOWNID(ARCH_ANY, "any"),
-
-KNOWNID(REPOSITORY_REPOMD_SIZE, "repository:repomd:size"),
-
KNOWNID(ID_NUM_INTERNAL, 0)
#ifdef KNOWNID_INITIALIZE
diff --git a/src/libsolv.ver b/src/libsolv.ver
index bc487ce..52b51da 100644
--- a/src/libsolv.ver
+++ b/src/libsolv.ver
@@ -19,6 +19,7 @@ SOLV_1.0 {
dataiterator_skip_repo;
dataiterator_skip_solvable;
dataiterator_step;
+ dataiterator_strdup;
datamatcher_free;
datamatcher_init;
datamatcher_match;
@@ -89,6 +90,7 @@ SOLV_1.0 {
pool_rel2id;
pool_search;
pool_selection2str;
+ pool_set_custom_vendorcheck;
pool_set_flag;
pool_set_installed;
pool_set_languages;
diff --git a/src/policy.c b/src/policy.c
index abd07e5..916590c 100644
--- a/src/policy.c
+++ b/src/policy.c
@@ -601,11 +601,6 @@ prune_to_best_version(Pool *pool, Queue *plist)
static void
prune_best_arch_name_version(const Solver *solv, Pool *pool, Queue *plist)
{
- if (solv && solv->bestSolvableCb)
- { /* The application is responsible for */
- return solv->bestSolvableCb(solv->pool, plist);
- }
-
if (plist->count > 1)
prune_to_best_arch(pool, plist);
if (plist->count > 1)
@@ -675,11 +670,6 @@ policy_illegal_archchange(Solver *solv, Solvable *s1, Solvable *s2)
Pool *pool = solv->pool;
Id a1 = s1->arch, a2 = s2->arch;
- if (solv && solv->archCheckCb)
- { /* The application is responsible for */
- return solv->archCheckCb(solv->pool, s1, s2);
- }
-
/* we allow changes to/from noarch */
if (a1 == a2 || a1 == pool->noarchid || a2 == pool->noarchid)
return 0;
@@ -701,10 +691,9 @@ policy_illegal_vendorchange(Solver *solv, Solvable *s1, Solvable *s2)
Id v1, v2;
Id vendormask1, vendormask2;
- if (solv->vendorCheckCb)
- { /* The application is responsible for */
- return solv->vendorCheckCb(pool, s1, s2);
- }
+ if (pool->custom_vendorcheck)
+ return pool->custom_vendorcheck(pool, s1, s2);
+
/* treat a missing vendor as empty string */
v1 = s1->vendor ? s1->vendor : ID_EMPTY;
v2 = s2->vendor ? s2->vendor : ID_EMPTY;
@@ -768,6 +757,8 @@ policy_create_obsolete_index(Solver *solv)
Id p, pp, obs, *obsp, *obsoletes, *obsoletes_data;
int i, n, cnt;
+ solv->obsoletes = solv_free(solv->obsoletes);
+ solv->obsoletes_data = solv_free(solv->obsoletes_data);
if (!installed || installed->start == installed->end)
return;
cnt = installed->end - installed->start;
@@ -867,11 +858,6 @@ policy_findupdatepackages(Solver *solv, Solvable *s, Queue *qs, int allow_all)
queue_empty(qs);
- if (solv && solv->updateCandidateCb)
- { /* The application is responsible for */
- return solv->updateCandidateCb(solv->pool, s, qs);
- }
-
n = s - pool->solvables;
/*
diff --git a/src/pool.c b/src/pool.c
index d8eb040..3b27318 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -758,6 +758,8 @@ pool_addrelproviders(Pool *pool, Id d)
continue;
if (s->arch != evr && s->arch != ARCH_NOSRC)
continue;
+ if (pool_disabled_solvable(pool, s))
+ continue;
if (pool_match_nevr(pool, s, name))
queue_push(&plist, p);
}
@@ -2096,6 +2098,39 @@ pool_lookup_deltalocation(Pool *pool, Id entry, unsigned int *medianrp)
return loc;
}
+static void
+add_new_provider(Pool *pool, Id id, Id p)
+{
+ Queue q;
+ Id *pp;
+
+ while (ISRELDEP(id))
+ {
+ Reldep *rd = GETRELDEP(pool, id);
+ id = rd->name;
+ }
+
+ queue_init(&q);
+ for (pp = pool->whatprovidesdata + pool->whatprovides[id]; *pp; pp++)
+ {
+ if (*pp == p)
+ {
+ queue_free(&q);
+ return;
+ }
+ if (*pp > p)
+ {
+ queue_push(&q, p);
+ p = 0;
+ }
+ queue_push(&q, *pp);
+ }
+ if (p)
+ queue_push(&q, p);
+ pool->whatprovides[id] = pool_queuetowhatprovides(pool, &q);
+ queue_free(&q);
+}
+
void
pool_add_fileconflicts_deps(Pool *pool, Queue *conflicts)
{
@@ -2107,7 +2142,6 @@ pool_add_fileconflicts_deps(Pool *pool, Queue *conflicts)
if (!conflicts->count)
return;
- pool_freewhatprovides(pool);
for (i = 0; i < conflicts->count; i += 5)
{
fn = conflicts->elements[i];
@@ -2119,6 +2153,10 @@ pool_add_fileconflicts_deps(Pool *pool, Queue *conflicts)
if (!s->repo)
continue;
s->provides = repo_addid_dep(s->repo, s->provides, id, SOLVABLE_FILEMARKER);
+ if (pool->whatprovides)
+ add_new_provider(pool, fn, p);
+ if (pool->whatprovides_rel)
+ pool->whatprovides_rel[GETRELID(id)] = 0; /* clear cache */
s = pool->solvables + q;
if (!s->repo)
continue;
@@ -2161,4 +2199,11 @@ pool_get_rootdir(Pool *pool)
return pool->rootdir;
}
+/* only used in libzypp */
+void
+pool_set_custom_vendorcheck(Pool *pool, int (*vendorcheck)(Pool *, Solvable *, Solvable *))
+{
+ pool->custom_vendorcheck = vendorcheck;
+}
+
/* EOF */
diff --git a/src/pool.h b/src/pool.h
index e785cd8..8e1a951 100644
--- a/src/pool.h
+++ b/src/pool.h
@@ -148,8 +148,8 @@ struct _Pool {
char *rootdir;
+ int (*custom_vendorcheck)(struct _Pool *, Solvable *, Solvable *);
#endif
-
};
#define DISTTYPE_RPM 0
@@ -223,6 +223,7 @@ extern void pool_debug(Pool *pool, int type, const char *format, ...) __attribut
extern void pool_setdebugcallback(Pool *pool, void (*debugcallback)(struct _Pool *, void *data, int type, const char *str), void *debugcallbackdata);
extern void pool_setdebugmask(Pool *pool, int mask);
extern void pool_setloadcallback(Pool *pool, int (*cb)(struct _Pool *, struct _Repodata *, void *), void *loadcbdata);
+extern void pool_set_custom_vendorcheck(Pool *pool, int (*vendorcheck)(struct _Pool *, Solvable *, Solvable *));
extern char *pool_alloctmpspace(Pool *pool, int len);
@@ -265,8 +266,7 @@ Id pool_id2langid(Pool *pool, Id id, const char *lang, int create);
int solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap, Map *noobsoletesmap);
int solvable_trivial_installable_repo(Solvable *s, struct _Repo *installed, Map *noobsoletesmap);
int solvable_trivial_installable_queue(Solvable *s, Queue *installed, Map *noobsoletesmap);
-struct _Solver; /* argh, needed for vendorchange callback FIXME */
-int solvable_is_irrelevant_patch(Solvable *s, Map *installedmap, struct _Solver *solv);
+int solvable_is_irrelevant_patch(Solvable *s, Map *installedmap);
void pool_create_state_maps(Pool *pool, Queue *installed, Map *installedmap, Map *conflictsmap);
diff --git a/src/repo.h b/src/repo.h
index 4f93d1e..a7a56ae 100644
--- a/src/repo.h
+++ b/src/repo.h
@@ -84,6 +84,19 @@ static inline Repo *pool_id2repo(Pool *pool, Id repoid)
return repoid < pool->nrepos ? pool->repos[repoid] : 0;
}
+static inline int pool_disabled_solvable(const Pool *pool, Solvable *s)
+{
+ if (s->repo && s->repo->disabled)
+ return 1;
+ if (pool->considered)
+ {
+ Id id = s - pool->solvables;
+ if (!MAPTST(pool->considered, id))
+ return 1;
+ }
+ return 0;
+}
+
static inline int pool_installable(const Pool *pool, Solvable *s)
{
if (!s->arch || s->arch == ARCH_SRC || s->arch == ARCH_NOSRC)
diff --git a/src/repo_write.c b/src/repo_write.c
index f6e9fd6..fd8ff40 100644
--- a/src/repo_write.c
+++ b/src/repo_write.c
@@ -976,6 +976,8 @@ static Id verticals[] = {
SOLVABLE_PKGID,
SOLVABLE_HDRID,
SOLVABLE_LEADSIGID,
+ SOLVABLE_CHANGELOG_AUTHOR,
+ SOLVABLE_CHANGELOG_TEXT,
0
};
diff --git a/src/repodata.c b/src/repodata.c
index 9d3bb6b..2462c10 100644
--- a/src/repodata.c
+++ b/src/repodata.c
@@ -474,7 +474,7 @@ static unsigned char *
get_vertical_data(Repodata *data, Repokey *key, Id off, Id len)
{
unsigned char *dp;
- if (!len)
+ if (len <= 0)
return 0;
if (off >= data->lastverticaloffset)
{
@@ -489,6 +489,7 @@ get_vertical_data(Repodata *data, Repokey *key, Id off, Id len)
off += data->verticaloffset[key - data->keys];
/* fprintf(stderr, "key %d page %d\n", key->name, off / REPOPAGE_BLOBSIZE); */
dp = repopagestore_load_page_range(&data->store, off / REPOPAGE_BLOBSIZE, (off + len - 1) / REPOPAGE_BLOBSIZE);
+ data->storestate++;
if (dp)
dp += off % REPOPAGE_BLOBSIZE;
return dp;
@@ -834,19 +835,21 @@ repodata_stringify(Pool *pool, Repodata *data, Repokey *key, KeyValue *kv, int f
case REPOKEY_TYPE_DIRSTRARRAY:
if (!(flags & SEARCH_FILES))
return 1; /* match just the basename */
+ if (kv->num)
+ return 1; /* already stringified */
/* Put the full filename into kv->str. */
kv->str = repodata_dir2str(data, kv->id, kv->str);
- /* And to compensate for that put the "empty" directory into
- kv->id, so that later calls to repodata_dir2str on this data
- come up with the same filename again. */
- kv->id = 0;
+ kv->num = 1; /* mark stringification */
return 1;
case REPOKEY_TYPE_MD5:
case REPOKEY_TYPE_SHA1:
case REPOKEY_TYPE_SHA256:
if (!(flags & SEARCH_CHECKSUMS))
return 0; /* skip em */
+ if (kv->num)
+ return 1; /* already stringified */
kv->str = repodata_chk2str(data, key->type, (const unsigned char *)kv->str);
+ kv->num = 1; /* mark stringification */
return 1;
default:
return 0;
@@ -1235,6 +1238,19 @@ void
dataiterator_init_clone(Dataiterator *di, Dataiterator *from)
{
*di = *from;
+ if (di->dupstr)
+ {
+ if (di->dupstr == di->kv.str)
+ {
+ di->dupstr = solv_malloc(di->dupstrn);
+ memcpy(di->dupstr, from->dupstr, di->dupstrn);
+ }
+ else
+ {
+ di->dupstr = 0;
+ di->dupstrn = 0;
+ }
+ }
memset(&di->matcher, 0, sizeof(di->matcher));
if (from->matcher.match)
datamatcher_init(&di->matcher, from->matcher.match, from->matcher.flags);
@@ -1319,6 +1335,8 @@ dataiterator_free(Dataiterator *di)
{
if (di->matcher.match)
datamatcher_free(&di->matcher);
+ if (di->dupstr)
+ solv_free(di->dupstr);
}
static inline unsigned char *
@@ -1366,6 +1384,15 @@ dataiterator_step(Dataiterator *di)
{
Id schema;
+ if (di->state == di_nextattr && di->key->storage == KEY_STORAGE_VERTICAL_OFFSET && di->vert_ddp && di->vert_storestate != di->data->storestate) {
+ unsigned int ddpoff = di->ddp - di->vert_ddp;
+ di->vert_off += ddpoff;
+ di->vert_len -= ddpoff;
+ di->ddp = di->vert_ddp = get_vertical_data(di->data, di->key, di->vert_off, di->vert_len);
+ di->vert_storestate = di->data->storestate;
+ if (!di->ddp)
+ di->state = di_nextkey;
+ }
for (;;)
{
switch (di->state)
@@ -1429,7 +1456,27 @@ dataiterator_step(Dataiterator *di)
case di_enterkey: di_enterkey:
di->kv.entry = -1;
di->key = di->data->keys + *di->keyp;
- di->ddp = get_data(di->data, di->key, &di->dp, di->keyp[1] && (!di->keyname || (di->flags & SEARCH_SUB) != 0) ? 1 : 0);
+ if (!di->dp)
+ goto di_nextkey;
+ /* this is get_data() modified to store vert_ data */
+ if (di->key->storage == KEY_STORAGE_VERTICAL_OFFSET)
+ {
+ Id off, len;
+ di->dp = data_read_id(di->dp, &off);
+ di->dp = data_read_id(di->dp, &len);
+ di->vert_ddp = di->ddp = get_vertical_data(di->data, di->key, off, len);
+ di->vert_off = off;
+ di->vert_len = len;
+ di->vert_storestate = di->data->storestate;
+ }
+ else if (di->key->storage == KEY_STORAGE_INCORE)
+ {
+ di->ddp = di->dp;
+ if (di->keyp[1] && (!di->keyname || (di->flags & SEARCH_SUB) != 0))
+ di->dp = data_skip_key(di->data, di->dp, di->key);
+ }
+ else
+ di->ddp = 0;
if (!di->ddp)
goto di_nextkey;
if (di->key->type == REPOKEY_TYPE_DELETED)
@@ -1683,6 +1730,14 @@ dataiterator_clonepos(Dataiterator *di, Dataiterator *from)
di->parents[i].kv.parent = &di->parents[i - 1].kv;
di->kv.parent = &di->parents[di->nparents - 1].kv;
}
+ di->dupstr = 0;
+ di->dupstrn = 0;
+ if (from->dupstr && from->dupstr == from->kv.str)
+ {
+ di->dupstrn = from->dupstrn;
+ di->dupstr = solv_malloc(from->dupstrn);
+ memcpy(di->dupstr, from->dupstr, di->dupstrn);
+ }
}
void
@@ -1829,6 +1884,60 @@ dataiterator_match(Dataiterator *di, Datamatcher *ma)
return datamatcher_match(ma, di->kv.str);
}
+void
+dataiterator_strdup(Dataiterator *di)
+{
+ int l = -1;
+
+ if (!di->kv.str || di->kv.str == di->dupstr)
+ return;
+ switch (di->key->type)
+ {
+ case REPOKEY_TYPE_MD5:
+ case REPOKEY_TYPE_SHA1:
+ case REPOKEY_TYPE_SHA256:
+ case REPOKEY_TYPE_DIRSTRARRAY:
+ if (di->kv.num) /* was it stringified into tmp space? */
+ l = strlen(di->kv.str) + 1;
+ break;
+ default:
+ break;
+ }
+ if (l < 0 && di->key->storage == KEY_STORAGE_VERTICAL_OFFSET)
+ {
+ switch (di->key->type)
+ {
+ case REPOKEY_TYPE_STR:
+ case REPOKEY_TYPE_DIRSTRARRAY:
+ l = strlen(di->kv.str) + 1;
+ break;
+ case REPOKEY_TYPE_MD5:
+ l = SIZEOF_MD5;
+ break;
+ case REPOKEY_TYPE_SHA1:
+ l = SIZEOF_SHA1;
+ break;
+ case REPOKEY_TYPE_SHA256:
+ l = SIZEOF_SHA256;
+ break;
+ case REPOKEY_TYPE_BINARY:
+ l = di->kv.num;
+ break;
+ }
+ }
+ if (l >= 0)
+ {
+ if (!di->dupstrn || di->dupstrn < l)
+ {
+ di->dupstrn = l + 16;
+ di->dupstr = solv_realloc(di->dupstr, di->dupstrn);
+ }
+ if (l)
+ memcpy(di->dupstr, di->kv.str, l);
+ di->kv.str = di->dupstr;
+ }
+}
+
/************************************************************************
* data modify functions
*/
@@ -3071,7 +3180,10 @@ void
repodata_disable_paging(Repodata *data)
{
if (maybe_load_repodata(data, 0))
- repopagestore_disable_paging(&data->store);
+ {
+ repopagestore_disable_paging(&data->store);
+ data->storestate++;
+ }
}
static void
diff --git a/src/repodata.h b/src/repodata.h
index 7ce415b..54fb3df 100644
--- a/src/repodata.h
+++ b/src/repodata.h
@@ -96,6 +96,7 @@ typedef struct _Repodata {
Id lastverticaloffset; /* end of verticals */
Repopagestore store; /* our page store */
+ Id storestate; /* incremented every time the store might change */
unsigned char *vincore; /* internal vertical data */
unsigned int vincorelen; /* data size */
diff --git a/src/repopack.h b/src/repopack.h
index 81b7b88..d75e61a 100644
--- a/src/repopack.h
+++ b/src/repopack.h
@@ -164,12 +164,15 @@ data_fetch(unsigned char *dp, KeyValue *kv, Repokey *key)
kv->num2 = 0;
return data_read_u32(dp, &kv->num);
case REPOKEY_TYPE_MD5:
+ kv->num = 0; /* not stringified yet */
kv->str = (const char *)dp;
return dp + SIZEOF_MD5;
case REPOKEY_TYPE_SHA1:
+ kv->num = 0; /* not stringified yet */
kv->str = (const char *)dp;
return dp + SIZEOF_SHA1;
case REPOKEY_TYPE_SHA256:
+ kv->num = 0; /* not stringified yet */
kv->str = (const char *)dp;
return dp + SIZEOF_SHA256;
case REPOKEY_TYPE_BINARY:
@@ -180,6 +183,7 @@ data_fetch(unsigned char *dp, KeyValue *kv, Repokey *key)
return data_read_ideof(dp, &kv->id, &kv->eof);
case REPOKEY_TYPE_DIRSTRARRAY:
dp = data_read_ideof(dp, &kv->id, &kv->eof);
+ kv->num = 0; /* not stringified yet */
kv->str = (const char *)dp;
return dp + strlen(kv->str) + 1;
case REPOKEY_TYPE_DIRNUMNUMARRAY:
diff --git a/src/rules.c b/src/rules.c
index f6facf4..1003878 100644
--- a/src/rules.c
+++ b/src/rules.c
@@ -377,6 +377,12 @@ solver_addrule(Solver *solv, Id p, Id d)
return r;
}
+void
+solver_shrinkrules(Solver *solv, int nrules)
+{
+ solv->nrules = nrules;
+ solv->rules = solv_extend_resize(solv->rules, solv->nrules, sizeof(Rule), RULES_BLOCK);
+}
/******************************************************************************
***
@@ -507,13 +513,15 @@ solver_addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m)
dontfix = 1; /* dont care about broken rpm deps */
}
- if (!dontfix
- && s->arch != ARCH_SRC
- && s->arch != ARCH_NOSRC
- && !pool_installable(pool, s))
+ if (!dontfix)
{
- POOL_DEBUG(SOLV_DEBUG_RULE_CREATION, "package %s [%d] is not installable\n", pool_solvable2str(pool, s), (Id)(s - pool->solvables));
- addrpmrule(solv, -n, 0, SOLVER_RULE_RPM_NOT_INSTALLABLE, 0);
+ if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC
+ ? pool_disabled_solvable(pool, s)
+ : !pool_installable(pool, s))
+ {
+ POOL_DEBUG(SOLV_DEBUG_RULE_CREATION, "package %s [%d] is not installable\n", pool_solvable2str(pool, s), (Id)(s - pool->solvables));
+ addrpmrule(solv, -n, 0, SOLVER_RULE_RPM_NOT_INSTALLABLE, 0);
+ }
}
/* yet another SUSE hack, sigh */
@@ -1822,17 +1830,46 @@ void
solver_reenablepolicyrules(Solver *solv, int jobidx)
{
Queue *job = &solv->job;
- int i, j;
+ int i, j, k, ai;
Queue q, allq;
Rule *r;
Id lastjob = -1;
- Id qbuf[32], allqbuf[128];
+ Id qbuf[32], allqbuf[32];
queue_init_buffer(&q, qbuf, sizeof(qbuf)/sizeof(*qbuf));
- queue_init_buffer(&allq, allqbuf, sizeof(allqbuf)/sizeof(*allqbuf));
jobtodisablelist(solv, job->elements[jobidx - 1], job->elements[jobidx], &q);
if (!q.count)
- return;
+ {
+ queue_free(&q);
+ return;
+ }
+ /* now remove everything from q that is disabled by other jobs */
+
+ /* first remove cleandeps packages, they count as DISABLE_UPDATE */
+ if (solv->cleandepsmap.size)
+ {
+ solver_createcleandepsmap(solv, &solv->cleandepsmap, 0);
+ for (j = k = 0; j < q.count; j += 2)
+ {
+ if (q.elements[j] == DISABLE_UPDATE)
+ {
+ Id p = q.elements[j + 1];
+ if (p >= solv->installed->start && p < solv->installed->end && MAPTST(&solv->cleandepsmap, p - solv->installed->start))
+ continue; /* remove element from q */
+ }
+ q.elements[k++] = q.elements[j];
+ q.elements[k++] = q.elements[j + 1];
+ }
+ q.count = k;
+ if (!q.count)
+ {
+ queue_free(&q);
+ return;
+ }
+ }
+
+ /* now go through the disable list of all other jobs */
+ queue_init_buffer(&allq, allqbuf, sizeof(allqbuf)/sizeof(*allqbuf));
for (i = solv->jobrules; i < solv->jobrules_end; i++)
{
r = solv->rules + i;
@@ -1843,22 +1880,35 @@ solver_reenablepolicyrules(Solver *solv, int jobidx)
continue;
lastjob = j;
jobtodisablelist(solv, job->elements[j], job->elements[j + 1], &allq);
+ if (!allq.count)
+ continue;
+ /* remove all elements in allq from q */
+ for (j = k = 0; j < q.count; j += 2)
+ {
+ Id type = q.elements[j], arg = q.elements[j + 1];
+ for (ai = 0; ai < allq.count; ai += 2)
+ if (allq.elements[ai] == type && allq.elements[ai + 1] == arg)
+ break;
+ if (ai < allq.count)
+ continue; /* found it in allq, remove element from q */
+ q.elements[k++] = q.elements[j];
+ q.elements[k++] = q.elements[j + 1];
+ }
+ q.count = k;
+ if (!q.count)
+ {
+ queue_free(&q);
+ queue_free(&allq);
+ return;
+ }
+ queue_empty(&allq);
}
- if (solv->cleandepsmap.size)
- {
- solver_createcleandepsmap(solv, &solv->cleandepsmap, 0);
- for (i = solv->installed->start; i < solv->installed->end; i++)
- if (MAPTST(&solv->cleandepsmap, i - solv->installed->start))
- queue_push2(&allq, DISABLE_UPDATE, i);
- }
+ queue_free(&allq);
+
+ /* now re-enable anything that's left in q */
for (j = 0; j < q.count; j += 2)
{
Id type = q.elements[j], arg = q.elements[j + 1];
- for (i = 0; i < allq.count; i += 2)
- if (allq.elements[i] == type && allq.elements[i + 1] == arg)
- break;
- if (i < allq.count)
- continue; /* still disabled */
switch(type)
{
case DISABLE_UPDATE:
@@ -1872,7 +1922,6 @@ solver_reenablepolicyrules(Solver *solv, int jobidx)
break;
}
}
- queue_free(&allq);
queue_free(&q);
}
diff --git a/src/rules.h b/src/rules.h
index 144b683..4d6b8ad 100644
--- a/src/rules.h
+++ b/src/rules.h
@@ -99,6 +99,7 @@ solver_enablerule(struct _Solver *solv, Rule *r)
extern Rule *solver_addrule(struct _Solver *solv, Id p, Id d);
extern void solver_unifyrules(struct _Solver *solv);
extern int solver_rulecmp(struct _Solver *solv, Rule *r1, Rule *r2);
+extern void solver_shrinkrules(struct _Solver *solv, int nrules);
/* rpm rules */
extern void solver_addrpmrulesforsolvable(struct _Solver *solv, Solvable *s, Map *m);
diff --git a/src/selection.c b/src/selection.c
index 2ef5e1e..c586a2c 100644
--- a/src/selection.c
+++ b/src/selection.c
@@ -121,7 +121,7 @@ selection_flatten(Pool *pool, Queue *selection)
{
Queue q;
int i;
- if (selection->count <= 1)
+ if (selection->count <= 2)
return;
for (i = 0; i < selection->count; i += 2)
if ((selection->elements[i] & SOLVER_SELECTMASK) == SOLVER_SOLVABLE_ALL)
@@ -155,6 +155,7 @@ static void
selection_filter_rel(Pool *pool, Queue *selection, Id relflags, Id relevr)
{
int i;
+
for (i = 0; i < selection->count; i += 2)
{
Id select = selection->elements[i] & SOLVER_SELECTMASK;
@@ -196,7 +197,7 @@ selection_filter_rel(Pool *pool, Queue *selection, Id relflags, Id relevr)
}
queue_free(&q);
}
- else if (select == SOLVER_SOLVABLE_NAME && select == SOLVER_SOLVABLE_PROVIDES)
+ else if (select == SOLVER_SOLVABLE_NAME || select == SOLVER_SOLVABLE_PROVIDES)
{
/* don't stack src reldeps */
if (relflags == REL_ARCH && (relevr == ARCH_SRC || relevr == ARCH_NOSRC) && ISRELDEP(id))
@@ -245,7 +246,11 @@ selection_addsrc(Pool *pool, Queue *selection, int flags)
if (s->name != name)
continue;
if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC)
- havesrc = 1;
+ {
+ if (pool_disabled_solvable(pool, s))
+ continue;
+ havesrc = 1;
+ }
else if (s->repo != pool->installed && !pool_installable(pool, s))
continue;
queue_push(&q, p);
@@ -316,6 +321,8 @@ selection_depglob(Pool *pool, Queue *selection, const char *name, int flags)
{
if ((flags & SELECTION_INSTALLED_ONLY) != 0 && s->repo != pool->installed)
continue; /* just in case... src rpms can't be installed */
+ if (pool_disabled_solvable(pool, s))
+ continue;
if ((flags & SELECTION_SOURCE_ONLY) != 0)
id = pool_rel2id(pool, id, ARCH_SRC, REL_ARCH, 1);
queue_push2(selection, SOLVER_SOLVABLE_NAME, id);
@@ -377,8 +384,12 @@ selection_depglob(Pool *pool, Queue *selection, const char *name, int flags)
{
Solvable *s = pool->solvables + p;
if (s->repo != pool->installed && !pool_installable(pool, s))
- if (!(flags & SELECTION_SOURCE_ONLY) || (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC))
- continue;
+ {
+ if (!(flags & SELECTION_SOURCE_ONLY) || (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC))
+ continue;
+ if (pool_disabled_solvable(pool, s))
+ continue;
+ }
if ((flags & SELECTION_INSTALLED_ONLY) != 0 && s->repo != pool->installed)
continue;
id = s->name;
@@ -476,8 +487,12 @@ selection_filelist(Pool *pool, Queue *selection, const char *name, int flags)
if (!s->repo)
continue;
if (s->repo != pool->installed && !pool_installable(pool, s))
- if (!(flags & SELECTION_SOURCE_ONLY) || (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC))
- continue;
+ {
+ if (!(flags & SELECTION_SOURCE_ONLY) || (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC))
+ continue;
+ if (pool_disabled_solvable(pool, s))
+ continue;
+ }
if ((flags & SELECTION_INSTALLED_ONLY) != 0 && s->repo != pool->installed)
continue;
queue_push(&q, di.solvid);
@@ -722,7 +737,8 @@ selection_make(Pool *pool, Queue *selection, const char *name, int flags)
ret = selection_depglob_arch(pool, selection, name, flags);
if (!ret && (flags & SELECTION_CANON) != 0)
ret = selection_canon(pool, selection, name, flags);
-
+ if (ret && !selection->count)
+ ret = 0; /* no match -> always return zero */
if (ret && (flags & SELECTION_FLAT) != 0)
selection_flatten(pool, selection);
return ret;
diff --git a/src/solvable.c b/src/solvable.c
index 4594544..7ac79ee 100644
--- a/src/solvable.c
+++ b/src/solvable.c
@@ -462,7 +462,7 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm
{
if (providedbyinstalled(pool, installedmap, con, ispatch, noobsoletesmap))
{
- if (ispatch && solvable_is_irrelevant_patch(s, installedmap, 0))
+ if (ispatch && solvable_is_irrelevant_patch(s, installedmap))
return -1;
return 0;
}
@@ -473,7 +473,7 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm
interesting = 1;
}
}
- if (ispatch && interesting && solvable_is_irrelevant_patch(s, installedmap, 0))
+ if (ispatch && interesting && solvable_is_irrelevant_patch(s, installedmap))
interesting = 0;
}
#if 0
@@ -575,11 +575,33 @@ solvable_trivial_installable_repo(Solvable *s, Repo *installed, Map *noobsoletes
return r;
}
+/* FIXME: this mirrors policy_illegal_vendorchange */
+static int
+pool_illegal_vendorchange(Pool *pool, Solvable *s1, Solvable *s2)
+{
+ Id v1, v2;
+ Id vendormask1, vendormask2;
+
+ if (pool->custom_vendorcheck)
+ return pool->custom_vendorcheck(pool, s1, s2);
+ /* treat a missing vendor as empty string */
+ v1 = s1->vendor ? s1->vendor : ID_EMPTY;
+ v2 = s2->vendor ? s2->vendor : ID_EMPTY;
+ if (v1 == v2)
+ return 0;
+ vendormask1 = pool_vendor2mask(pool, v1);
+ if (!vendormask1)
+ return 1; /* can't match */
+ vendormask2 = pool_vendor2mask(pool, v2);
+ if ((vendormask1 & vendormask2) != 0)
+ return 0;
+ return 1; /* no class matches */
+}
/* check if this patch is relevant according to the vendor. To bad that patches
* don't have a vendor, so we need to do some careful repo testing. */
int
-solvable_is_irrelevant_patch(Solvable *s, Map *installedmap, Solver *solv)
+solvable_is_irrelevant_patch(Solvable *s, Map *installedmap)
{
Pool *pool = s->repo->pool;
Id con, *conp;
@@ -618,23 +640,8 @@ solvable_is_irrelevant_patch(Solvable *s, Map *installedmap, Solver *solv)
/* ok, we have a package from the patch repo that solves the conflict. check vendor */
if (si->vendor == s2->vendor)
return 0;
- /* FIXME: solv is only needed for the vendorchange callback */
- if (solv)
- {
- if (!policy_illegal_vendorchange(solv, si, s2))
- return 0;
- }
- else
- {
- Id v1 = si->vendor ? si->vendor : ID_EMPTY;
- Id v2 = s2->vendor ? s2->vendor : ID_EMPTY;
- if (v1 == v2)
- return 0;
- v1 = pool_vendor2mask(pool, v1);
- v2 = pool_vendor2mask(pool, v2);
- if ((v1 & v2) != 0)
- return 0;
- }
+ if (!pool_illegal_vendorchange(pool, si, s2))
+ return 0;
/* vendor change was illegal, ignore conflict */
}
}
diff --git a/src/solver.c b/src/solver.c
index 43668d5..c1518db 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -965,11 +965,11 @@ solver_reset(Solver *solv)
v = solv->decisionq.elements[i];
solv->decisionmap[v > 0 ? v : -v] = 0;
}
- solv->decisionq_why.count = 0;
- solv->decisionq.count = 0;
+ queue_empty(&solv->decisionq_why);
+ queue_empty(&solv->decisionq);
solv->recommends_index = -1;
solv->propagate_index = 0;
- solv->branches.count = 0;
+ queue_empty(&solv->branches);
/* adapt learnt rule status to new set of enabled/disabled rules */
enabledisablelearntrules(solv);
@@ -1436,6 +1436,7 @@ solver_create(Pool *pool)
queue_init(&solv->branches);
queue_init(&solv->weakruleq);
queue_init(&solv->ruleassertions);
+ queue_init(&solv->addedmap_deduceq);
queue_push(&solv->learnt_pool, 0); /* so that 0 does not describe a proof */
@@ -1473,6 +1474,7 @@ solver_free(Solver *solv)
queue_free(&solv->branches);
queue_free(&solv->weakruleq);
queue_free(&solv->ruleassertions);
+ queue_free(&solv->addedmap_deduceq);
if (solv->cleandeps_updatepkgs)
{
queue_free(solv->cleandeps_updatepkgs);
@@ -2831,6 +2833,74 @@ transform_update_targets(Solver *solv)
}
+static void
+addedmap2deduceq(Solver *solv, Map *addedmap)
+{
+ Pool *pool = solv->pool;
+ int i, j;
+ Id p;
+ Rule *r;
+
+ queue_empty(&solv->addedmap_deduceq);
+ for (i = 2, j = solv->rpmrules_end - 1; i < pool->nsolvables && j > 0; j--)
+ {
+ r = solv->rules + j;
+ if (r->p >= 0)
+ continue;
+ if ((r->d == 0 || r->d == -1) && r->w2 < 0)
+ continue;
+ p = -r->p;
+ if (!MAPTST(addedmap, p))
+ {
+ /* should never happen, but... */
+ if (!solv->addedmap_deduceq.count || solv->addedmap_deduceq.elements[solv->addedmap_deduceq.count - 1] != -p)
+ queue_push(&solv->addedmap_deduceq, -p);
+ continue;
+ }
+ for (; i < p; i++)
+ if (MAPTST(addedmap, i))
+ queue_push(&solv->addedmap_deduceq, i);
+ if (i == p)
+ i++;
+ }
+ for (; i < pool->nsolvables; i++)
+ if (MAPTST(addedmap, i))
+ queue_push(&solv->addedmap_deduceq, i);
+ j = 0;
+ for (i = 2; i < pool->nsolvables; i++)
+ if (MAPTST(addedmap, i))
+ j++;
+}
+
+static void
+deduceq2addedmap(Solver *solv, Map *addedmap)
+{
+ int j;
+ Id p;
+ Rule *r;
+ for (j = solv->rpmrules_end - 1; j > 0; j--)
+ {
+ r = solv->rules + j;
+ if (r->d < 0 && r->p)
+ solver_enablerule(solv, r);
+ if (r->p >= 0)
+ continue;
+ if ((r->d == 0 || r->d == -1) && r->w2 < 0)
+ continue;
+ p = -r->p;
+ MAPSET(addedmap, p);
+ }
+ for (j = 0; j < solv->addedmap_deduceq.count; j++)
+ {
+ p = solv->addedmap_deduceq.elements[j];
+ if (p > 0)
+ MAPSET(addedmap, p);
+ else
+ MAPCLR(addedmap, p);
+ }
+}
+
+
/*
*
* solve job queue
@@ -2843,7 +2913,7 @@ solver_solve(Solver *solv, Queue *job)
Pool *pool = solv->pool;
Repo *installed = solv->installed;
int i;
- int oldnrules;
+ int oldnrules, initialnrules;
Map addedmap; /* '1' == have rpm-rules for solvable */
Map installcandidatemap;
Id how, what, select, name, weak, p, pp, d;
@@ -2893,6 +2963,81 @@ solver_solve(Solver *solv, Queue *job)
queue_free(solv->cleandeps_updatepkgs);
solv->cleandeps_updatepkgs = solv_free(solv->cleandeps_updatepkgs);
}
+ queue_empty(&solv->ruleassertions);
+ solv->bestrules_pkg = solv_free(solv->bestrules_pkg);
+ solv->choicerules_ref = solv_free(solv->choicerules_ref);
+ if (solv->noupdate.size)
+ map_empty(&solv->noupdate);
+ if (solv->noobsoletes.size)
+ {
+ map_free(&solv->noobsoletes);
+ map_init(&solv->noobsoletes, 0);
+ }
+ solv->updatemap_all = 0;
+ if (solv->updatemap.size)
+ {
+ map_free(&solv->updatemap);
+ map_init(&solv->updatemap, 0);
+ }
+ solv->bestupdatemap_all = 0;
+ if (solv->bestupdatemap.size)
+ {
+ map_free(&solv->bestupdatemap);
+ map_init(&solv->bestupdatemap, 0);
+ }
+ solv->fixmap_all = 0;
+ if (solv->fixmap.size)
+ {
+ map_free(&solv->fixmap);
+ map_init(&solv->fixmap, 0);
+ }
+ solv->dupmap_all = 0;
+ if (solv->dupmap.size)
+ {
+ map_free(&solv->dupmap);
+ map_init(&solv->dupmap, 0);
+ }
+ if (solv->dupinvolvedmap.size)
+ {
+ map_free(&solv->dupinvolvedmap);
+ map_init(&solv->dupinvolvedmap, 0);
+ }
+ solv->droporphanedmap_all = 0;
+ if (solv->droporphanedmap.size)
+ {
+ map_free(&solv->droporphanedmap);
+ map_init(&solv->droporphanedmap, 0);
+ }
+ if (solv->cleandepsmap.size)
+ {
+ map_free(&solv->cleandepsmap);
+ map_init(&solv->cleandepsmap, 0);
+ }
+
+ queue_empty(&solv->weakruleq);
+ solv->watches = solv_free(solv->watches);
+ queue_empty(&solv->ruletojob);
+ if (solv->decisionq.count)
+ memset(solv->decisionmap, 0, pool->nsolvables * sizeof(Id));
+ queue_empty(&solv->decisionq);
+ queue_empty(&solv->decisionq_why);
+ solv->decisioncnt_update = solv->decisioncnt_keep = solv->decisioncnt_resolve = solv->decisioncnt_weak = solv->decisioncnt_orphan = 0;
+ queue_empty(&solv->learnt_why);
+ queue_empty(&solv->learnt_pool);
+ queue_empty(&solv->branches);
+ solv->propagate_index = 0;
+ queue_empty(&solv->problems);
+ queue_empty(&solv->solutions);
+ queue_empty(&solv->orphaned);
+ solv->stats_learned = solv->stats_unsolvable = 0;
+ if (solv->recommends_index)
+ {
+ map_empty(&solv->recommendsmap);
+ map_empty(&solv->suggestsmap);
+ solv->recommends_index = 0;
+ }
+ solv->multiversionupdaters = solv_free(solv->multiversionupdaters);
+
/*
* create basic rule set of all involved packages
@@ -2914,6 +3059,14 @@ solver_solve(Solver *solv, Queue *job)
* so called: rpm rules
*
*/
+ initialnrules = solv->rpmrules_end ? solv->rpmrules_end : 1;
+ if (initialnrules > 1)
+ deduceq2addedmap(solv, &addedmap);
+ if (solv->nrules != initialnrules)
+ solver_shrinkrules(solv, initialnrules);
+ solv->nrules = initialnrules;
+ solv->rpmrules_end = 0;
+
if (installed)
{
/* check for update/verify jobs as they need to be known early */
@@ -3087,8 +3240,12 @@ solver_solve(Solver *solv, Queue *job)
POOL_DEBUG(SOLV_DEBUG_STATS, "%d of %d installable solvables considered for solving\n", possible, installable);
}
- solver_unifyrules(solv); /* remove duplicate rpm rules */
- solv->rpmrules_end = solv->nrules; /* mark end of rpm rules */
+ if (solv->nrules > initialnrules)
+ solver_unifyrules(solv); /* remove duplicate rpm rules */
+ solv->rpmrules_end = solv->nrules; /* mark end of rpm rules */
+
+ if (solv->nrules > initialnrules)
+ addedmap2deduceq(solv, &addedmap); /* so that we can recreate the addedmap */
POOL_DEBUG(SOLV_DEBUG_STATS, "rpm rule memory used: %d K\n", solv->nrules * (int)sizeof(Rule) / 1024);
POOL_DEBUG(SOLV_DEBUG_STATS, "rpm rule creation took %d ms\n", solv_timems(now));
@@ -3754,7 +3911,7 @@ solver_trivial_installable(Solver *solv, Queue *pkgs, Queue *res)
if (res->elements[i] != -1)
{
Solvable *s = pool->solvables + pkgs->elements[i];
- if (!strncmp("patch:", pool_id2str(pool, s->name), 6) && solvable_is_irrelevant_patch(s, &installedmap, solv))
+ if (!strncmp("patch:", pool_id2str(pool, s->name), 6) && solvable_is_irrelevant_patch(s, &installedmap))
res->elements[i] = -1;
}
map_free(&installedmap);
diff --git a/src/solver.h b/src/solver.h
index a134718..b735329 100644
--- a/src/solver.h
+++ b/src/solver.h
@@ -26,15 +26,6 @@ extern "C" {
#include "rules.h"
#include "problems.h"
-/*
- * Callback definitions in order to "overwrite" the policies by an external application.
- */
-
-typedef void (*BestSolvableCb) (Pool *pool, Queue *canditates);
-typedef int (*ArchCheckCb) (Pool *pool, Solvable *solvable1, Solvable *solvable2);
-typedef int (*VendorCheckCb) (Pool *pool, Solvable *solvable1, Solvable *solvable2);
-typedef void (*UpdateCandidateCb) (Pool *pool, Solvable *solvable, Queue *canditates);
-
struct _Solver {
Pool *pool; /* back pointer to pool */
@@ -43,46 +34,7 @@ struct _Solver {
int (*solution_callback)(struct _Solver *solv, void *data);
void *solution_callback_data;
- /* Callbacks for defining the bahaviour of the solver */
-
- /* Finding best candidate
- *
- * Callback definition:
- * void bestSolvable (Pool *pool, Queue *canditates)
- * candidates : List of canditates which has to be sorted by the function call
- * return candidates: Sorted list of the candidates(first is the best).
- */
- BestSolvableCb bestSolvableCb;
-
- /* Checking if two solvables has compatible architectures
- *
- * Callback definition:
- * int archCheck (Pool *pool, Solvable *solvable1, Solvable *solvable2);
- *
- * return 0 it the two solvables has compatible architectures
- */
- ArchCheckCb archCheckCb;
-
- /* Checking if two solvables has compatible vendors
- *
- * Callback definition:
- * int vendorCheck (Pool *pool, Solvable *solvable1, Solvable *solvable2);
- *
- * return 0 it the two solvables has compatible architectures
- */
- VendorCheckCb vendorCheckCb;
-
- /* Evaluate update candidate
- *
- * Callback definition:
- * void UpdateCandidateCb (Pool *pool, Solvable *solvable, Queue *canditates)
- * solvable : for which updates should be search
- * candidates : List of candidates (This list depends on other
- * restrictions like architecture and vendor policies too)
- */
- UpdateCandidateCb updateCandidateCb;
-
- int pooljobcnt; /* number of pooljob entries in job queue */
+ int pooljobcnt; /* number of pooljob entries in job queue */
#ifdef LIBSOLV_INTERNAL
Repo *installed; /* copy of pool->installed */
@@ -229,6 +181,8 @@ struct _Solver {
Queue *update_targets; /* update to specific packages */
Queue *installsuppdepq; /* deps from the install namespace provides hack */
+
+ Queue addedmap_deduceq; /* deduce addedmap from rpm rules */
#endif /* LIBSOLV_INTERNAL */
};