Apply 9 patches from upstream
This commit is contained in:
parent
a48fd05882
commit
78b212e337
@ -0,0 +1,79 @@
|
|||||||
|
From f362259ac2f92c6c1914974032f2f7c436ac00d4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
Date: Fri, 26 Feb 2016 11:45:09 +0100
|
||||||
|
Subject: [PATCH 1/9] Add repodata_lookup_dirstrarray_uninternalized method
|
||||||
|
|
||||||
|
Needed for next commit.
|
||||||
|
---
|
||||||
|
src/libsolv.ver | 1 +
|
||||||
|
src/repodata.c | 25 +++++++++++++++++++++++++
|
||||||
|
src/repodata.h | 3 +++
|
||||||
|
3 files changed, 29 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/libsolv.ver b/src/libsolv.ver
|
||||||
|
index 6508288..cc79704 100644
|
||||||
|
--- a/src/libsolv.ver
|
||||||
|
+++ b/src/libsolv.ver
|
||||||
|
@@ -201,6 +201,7 @@ SOLV_1.0 {
|
||||||
|
repodata_key2id;
|
||||||
|
repodata_localize_id;
|
||||||
|
repodata_lookup_bin_checksum;
|
||||||
|
+ repodata_lookup_bin_checksum_uninternalized;
|
||||||
|
repodata_lookup_binary;
|
||||||
|
repodata_lookup_dirstrarray_uninternalized;
|
||||||
|
repodata_lookup_id;
|
||||||
|
diff --git a/src/repodata.c b/src/repodata.c
|
||||||
|
index ad3e71a..b611afc 100644
|
||||||
|
--- a/src/repodata.c
|
||||||
|
+++ b/src/repodata.c
|
||||||
|
@@ -881,6 +881,31 @@ repodata_lookup_dirstrarray_uninternalized(Repodata *data, Id solvid, Id keyname
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+const unsigned char *
|
||||||
|
+repodata_lookup_bin_checksum_uninternalized(Repodata *data, Id solvid, Id keyname, Id *typep)
|
||||||
|
+{
|
||||||
|
+ Id *ap;
|
||||||
|
+ if (!data->attrs)
|
||||||
|
+ return 0;
|
||||||
|
+ ap = data->attrs[solvid - data->start];
|
||||||
|
+ if (!ap)
|
||||||
|
+ return 0;
|
||||||
|
+ for (; *ap; ap += 2)
|
||||||
|
+ {
|
||||||
|
+ if (data->keys[*ap].name != keyname)
|
||||||
|
+ continue;
|
||||||
|
+ switch (data->keys[*ap].type)
|
||||||
|
+ {
|
||||||
|
+ case_CHKSUM_TYPES:
|
||||||
|
+ *typep = data->keys[*ap].type;
|
||||||
|
+ return (const unsigned char *)data->attrdata + ap[1];
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/************************************************************************
|
||||||
|
* data search
|
||||||
|
*/
|
||||||
|
diff --git a/src/repodata.h b/src/repodata.h
|
||||||
|
index c18c688..d72c60f 100644
|
||||||
|
--- a/src/repodata.h
|
||||||
|
+++ b/src/repodata.h
|
||||||
|
@@ -300,8 +300,11 @@ const char *repodata_chk2str(Repodata *data, Id type, const unsigned char *buf);
|
||||||
|
void repodata_set_location(Repodata *data, Id solvid, int medianr, const char *dir, const char *file);
|
||||||
|
void repodata_set_deltalocation(Repodata *data, Id handle, int medianr, const char *dir, const char *file);
|
||||||
|
void repodata_set_sourcepkg(Repodata *data, Id solvid, const char *sourcepkg);
|
||||||
|
+
|
||||||
|
+/* uninternalized data lookup */
|
||||||
|
Id repodata_lookup_id_uninternalized(Repodata *data, Id solvid, Id keyname, Id voidid);
|
||||||
|
const char *repodata_lookup_dirstrarray_uninternalized(Repodata *data, Id solvid, Id keyname, Id *didp, Id *iterp);
|
||||||
|
+const unsigned char *repodata_lookup_bin_checksum_uninternalized(Repodata *data, Id solvid, Id keyname, Id *typep);
|
||||||
|
|
||||||
|
/* stats */
|
||||||
|
unsigned int repodata_memused(Repodata *data);
|
||||||
|
--
|
||||||
|
2.5.0
|
||||||
|
|
272
0003-Do-not-create-a-checksum-hash-when-we-re-not-extendi.patch
Normal file
272
0003-Do-not-create-a-checksum-hash-when-we-re-not-extendi.patch
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
From 0280a6a08344a11c8fd0e0226263cc8a808fd4c1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
Date: Fri, 26 Feb 2016 11:45:27 +0100
|
||||||
|
Subject: [PATCH 2/9] Do not create a checksum hash when we're not extending
|
||||||
|
|
||||||
|
Many repos don't have extension data, so we postpone the
|
||||||
|
hash creation until we need it.
|
||||||
|
---
|
||||||
|
ext/repo_rpmmd.c | 165 +++++++++++++++++++++++++++++++++++++++----------------
|
||||||
|
1 file changed, 117 insertions(+), 48 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ext/repo_rpmmd.c b/ext/repo_rpmmd.c
|
||||||
|
index a45d491..cc54b3e 100644
|
||||||
|
--- a/ext/repo_rpmmd.c
|
||||||
|
+++ b/ext/repo_rpmmd.c
|
||||||
|
@@ -258,12 +258,18 @@ struct parsedata {
|
||||||
|
|
||||||
|
Id changelog_handle;
|
||||||
|
|
||||||
|
- /** Hash to maps checksums to solv */
|
||||||
|
+ int extending; /* are we extending an existing solvable? */
|
||||||
|
+
|
||||||
|
+ /* first solvable we added */
|
||||||
|
+ int first;
|
||||||
|
+ /* cspool ok to use */
|
||||||
|
+ int cshash_filled;
|
||||||
|
+ /* Hash to maps checksums to solv */
|
||||||
|
Stringpool cspool;
|
||||||
|
- /** Cache of known checksums to solvable id */
|
||||||
|
- Id *cscache;
|
||||||
|
+ /* Cache of known checksums to solvable id */
|
||||||
|
+ Id *cshash;
|
||||||
|
/* the current longest index in the table */
|
||||||
|
- int ncscache;
|
||||||
|
+ int ncshash;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Id
|
||||||
|
@@ -576,6 +582,83 @@ set_description_author(Repodata *data, Id handle, char *str, struct parsedata *p
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+init_cshash(struct parsedata *pd)
|
||||||
|
+{
|
||||||
|
+ /* initialize the string pool where we will store
|
||||||
|
+ the package checksums we know about, to get an Id
|
||||||
|
+ we can use in a cache */
|
||||||
|
+ stringpool_init_empty(&pd->cspool);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+free_cshash(struct parsedata *pd)
|
||||||
|
+{
|
||||||
|
+ stringpool_free(&pd->cspool);
|
||||||
|
+ solv_free(pd->cshash);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* save the checksum as key to solvable id relationship for
|
||||||
|
+ metadata extension */
|
||||||
|
+static void
|
||||||
|
+put_in_cshash(struct parsedata *pd, const char *key, Id id)
|
||||||
|
+{
|
||||||
|
+ Id index = stringpool_str2id(&pd->cspool, key, 1);
|
||||||
|
+ if (index >= pd->ncshash)
|
||||||
|
+ {
|
||||||
|
+ pd->cshash = solv_zextend(pd->cshash, pd->ncshash, index + 1 - pd->ncshash, sizeof(Id), 255);
|
||||||
|
+ pd->ncshash = index + 1;
|
||||||
|
+ }
|
||||||
|
+ /* add the checksum to the cache */
|
||||||
|
+ pd->cshash[index] = id;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static Id
|
||||||
|
+lookup_cshash(struct parsedata *pd, const char *key)
|
||||||
|
+{
|
||||||
|
+ Id index = stringpool_str2id(&pd->cspool, key, 0);
|
||||||
|
+ if (!index || index >= pd->ncshash || !pd->cshash[index])
|
||||||
|
+ return 0;
|
||||||
|
+ return pd->cshash[index];
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+fill_cshash_from_repo(struct parsedata *pd)
|
||||||
|
+{
|
||||||
|
+ Dataiterator di;
|
||||||
|
+ /* setup join data */
|
||||||
|
+ dataiterator_init(&di, pd->pool, pd->repo, 0, SOLVABLE_CHECKSUM, 0, 0);
|
||||||
|
+ while (dataiterator_step(&di))
|
||||||
|
+ {
|
||||||
|
+ const char *str;
|
||||||
|
+
|
||||||
|
+ if (!solv_chksum_len(di.key->type))
|
||||||
|
+ continue;
|
||||||
|
+ str = repodata_chk2str(di.data, di.key->type, (const unsigned char *)di.kv.str);
|
||||||
|
+ put_in_cshash(pd, str, di.solvid);
|
||||||
|
+ }
|
||||||
|
+ dataiterator_free(&di);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+fill_cshash_from_new_solvables(struct parsedata *pd)
|
||||||
|
+{
|
||||||
|
+ Pool *pool = pd->pool;
|
||||||
|
+ Id cstype;
|
||||||
|
+ unsigned const char *cs;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = pd->first; i < pool->nsolvables; i++)
|
||||||
|
+ {
|
||||||
|
+ if (pool->solvables[i].repo != pd->repo)
|
||||||
|
+ continue;
|
||||||
|
+ cs = repodata_lookup_bin_checksum_uninternalized(pd->data, i, SOLVABLE_CHECKSUM, &cstype);
|
||||||
|
+ if (cs)
|
||||||
|
+ put_in_cshash(pd, repodata_chk2str(pd->data, cstype, cs), i);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*-----------------------------------------------*/
|
||||||
|
/* XML callbacks */
|
||||||
|
|
||||||
|
@@ -664,26 +747,35 @@ startElement(void *userData, const char *name, const char **atts)
|
||||||
|
a new solvable but just append the attributes to the existing
|
||||||
|
one.
|
||||||
|
*/
|
||||||
|
+ pd->extending = 0;
|
||||||
|
if ((pkgid = find_attr("pkgid", atts)) != NULL)
|
||||||
|
{
|
||||||
|
+ if (!pd->cshash_filled)
|
||||||
|
+ {
|
||||||
|
+ pd->cshash_filled = 1;
|
||||||
|
+ fill_cshash_from_new_solvables(pd);
|
||||||
|
+ }
|
||||||
|
/* look at the checksum cache */
|
||||||
|
- Id index = stringpool_str2id(&pd->cspool, pkgid, 0);
|
||||||
|
- if (!index || index >= pd->ncscache || !pd->cscache[index])
|
||||||
|
+ handle = lookup_cshash(pd, pkgid);
|
||||||
|
+ if (!handle)
|
||||||
|
{
|
||||||
|
pool_debug(pool, SOLV_WARN, "the repository specifies extra information about package with checksum '%s', which does not exist in the repository.\n", pkgid);
|
||||||
|
- pd->solvable = 0;
|
||||||
|
pd->handle = 0;
|
||||||
|
+ pd->solvable = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- pd->solvable = pool_id2solvable(pool, pd->cscache[index]);
|
||||||
|
+ pd->extending = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* this is a new package */
|
||||||
|
- pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->repo));
|
||||||
|
+ handle = repo_add_solvable(pd->repo);
|
||||||
|
+ if (!pd->first)
|
||||||
|
+ pd->first = handle;
|
||||||
|
pd->freshens = 0;
|
||||||
|
}
|
||||||
|
- pd->handle = handle = pd->solvable - pool->solvables;
|
||||||
|
+ pd->handle = handle;
|
||||||
|
+ pd->solvable = pool_id2solvable(pool, handle);
|
||||||
|
if (pd->kind && pd->kind[1] == 'r')
|
||||||
|
{
|
||||||
|
/* products can have a type */
|
||||||
|
@@ -697,6 +789,8 @@ startElement(void *userData, const char *name, const char **atts)
|
||||||
|
|
||||||
|
break;
|
||||||
|
case STATE_VERSION:
|
||||||
|
+ if (pd->extending && s->evr)
|
||||||
|
+ break; /* ignore version tag repetition in extend data */
|
||||||
|
s->evr = makeevr_atts(pool, pd, atts);
|
||||||
|
break;
|
||||||
|
case STATE_PROVIDES:
|
||||||
|
@@ -923,6 +1017,11 @@ endElement(void *userData, const char *name)
|
||||||
|
switch (pd->state)
|
||||||
|
{
|
||||||
|
case STATE_SOLVABLE:
|
||||||
|
+ if (pd->extending)
|
||||||
|
+ {
|
||||||
|
+ pd->solvable = 0;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
if (pd->kind && !s->name) /* add namespace in case of NULL name */
|
||||||
|
s->name = pool_str2id(pool, join2(&pd->jd, pd->kind, ":", 0), 1);
|
||||||
|
if (!s->arch)
|
||||||
|
@@ -935,7 +1034,7 @@ endElement(void *userData, const char *name)
|
||||||
|
s->conflicts = repo_fix_conflicts(repo, s->conflicts);
|
||||||
|
pd->freshens = 0;
|
||||||
|
pd->kind = 0;
|
||||||
|
- pd->solvable = s = 0;
|
||||||
|
+ pd->solvable = 0;
|
||||||
|
break;
|
||||||
|
case STATE_NAME:
|
||||||
|
if (pd->kind)
|
||||||
|
@@ -957,8 +1056,6 @@ endElement(void *userData, const char *name)
|
||||||
|
break;
|
||||||
|
case STATE_CHECKSUM:
|
||||||
|
{
|
||||||
|
- Id index;
|
||||||
|
-
|
||||||
|
if (!pd->chksumtype)
|
||||||
|
break;
|
||||||
|
if (strlen(pd->content) != 2 * solv_chksum_len(pd->chksumtype))
|
||||||
|
@@ -967,16 +1064,9 @@ endElement(void *userData, const char *name)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
repodata_set_checksum(pd->data, handle, SOLVABLE_CHECKSUM, pd->chksumtype, pd->content);
|
||||||
|
- /* we save the checksum to solvable id relationship for extended
|
||||||
|
- metadata */
|
||||||
|
- index = stringpool_str2id(&pd->cspool, pd->content, 1 /* create it */);
|
||||||
|
- if (index >= pd->ncscache)
|
||||||
|
- {
|
||||||
|
- pd->cscache = solv_zextend(pd->cscache, pd->ncscache, index + 1 - pd->ncscache, sizeof(Id), 255);
|
||||||
|
- pd->ncscache = index + 1;
|
||||||
|
- }
|
||||||
|
- /* add the checksum to the cache */
|
||||||
|
- pd->cscache[index] = s - pool->solvables;
|
||||||
|
+ /* we save the checksum to solvable id relationship for extending metadata */
|
||||||
|
+ if (pd->cshash_filled)
|
||||||
|
+ put_in_cshash(pd, pd->content, s - pool->solvables);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STATE_FILE:
|
||||||
|
@@ -1165,32 +1255,12 @@ repo_add_rpmmd(Repo *repo, FILE *fp, const char *language, int flags)
|
||||||
|
pd.kind = 0;
|
||||||
|
pd.language = language && *language && strcmp(language, "en") != 0 ? language : 0;
|
||||||
|
|
||||||
|
- /* initialize the string pool where we will store
|
||||||
|
- the package checksums we know about, to get an Id
|
||||||
|
- we can use in a cache */
|
||||||
|
- stringpool_init_empty(&pd.cspool);
|
||||||
|
+ init_cshash(&pd);
|
||||||
|
if ((flags & REPO_EXTEND_SOLVABLES) != 0)
|
||||||
|
{
|
||||||
|
/* setup join data */
|
||||||
|
- Dataiterator di;
|
||||||
|
- dataiterator_init(&di, pool, repo, 0, SOLVABLE_CHECKSUM, 0, 0);
|
||||||
|
- while (dataiterator_step(&di))
|
||||||
|
- {
|
||||||
|
- const char *str;
|
||||||
|
- int index;
|
||||||
|
-
|
||||||
|
- if (!solv_chksum_len(di.key->type))
|
||||||
|
- continue;
|
||||||
|
- str = repodata_chk2str(di.data, di.key->type, (const unsigned char *)di.kv.str);
|
||||||
|
- index = stringpool_str2id(&pd.cspool, str, 1);
|
||||||
|
- if (index >= pd.ncscache)
|
||||||
|
- {
|
||||||
|
- pd.cscache = solv_zextend(pd.cscache, pd.ncscache, index + 1 - pd.ncscache, sizeof(Id), 255);
|
||||||
|
- pd.ncscache = index + 1;
|
||||||
|
- }
|
||||||
|
- pd.cscache[index] = di.solvid;
|
||||||
|
- }
|
||||||
|
- dataiterator_free(&di);
|
||||||
|
+ pd.cshash_filled = 1;
|
||||||
|
+ fill_cshash_from_repo(&pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
parser = XML_ParserCreate(NULL);
|
||||||
|
@@ -1213,8 +1283,7 @@ repo_add_rpmmd(Repo *repo, FILE *fp, const char *language, int flags)
|
||||||
|
solv_free(pd.content);
|
||||||
|
solv_free(pd.lastdirstr);
|
||||||
|
join_freemem(&pd.jd);
|
||||||
|
- stringpool_free(&pd.cspool);
|
||||||
|
- solv_free(pd.cscache);
|
||||||
|
+ free_cshash(&pd);
|
||||||
|
repodata_free_dircache(data);
|
||||||
|
|
||||||
|
if (!(flags & REPO_NO_INTERNALIZE))
|
||||||
|
--
|
||||||
|
2.5.0
|
||||||
|
|
34
0004-solv_hex2bin-don-t-eat-nibbles.patch
Normal file
34
0004-solv_hex2bin-don-t-eat-nibbles.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
From 4cebb81db05fd9281a6d482adce25c93605ed5da Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
Date: Fri, 26 Feb 2016 13:40:28 +0100
|
||||||
|
Subject: [PATCH 3/9] solv_hex2bin: don't eat nibbles
|
||||||
|
|
||||||
|
---
|
||||||
|
src/util.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/util.c b/src/util.c
|
||||||
|
index d611297..b2e9179 100644
|
||||||
|
--- a/src/util.c
|
||||||
|
+++ b/src/util.c
|
||||||
|
@@ -235,7 +235,7 @@ solv_hex2bin(const char **strp, unsigned char *buf, int bufl)
|
||||||
|
d = c - ('A' - 10);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
- c = *++str;
|
||||||
|
+ c = str[1];
|
||||||
|
d <<= 4;
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
d |= c - '0';
|
||||||
|
@@ -246,7 +246,7 @@ solv_hex2bin(const char **strp, unsigned char *buf, int bufl)
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
buf[i] = d;
|
||||||
|
- ++str;
|
||||||
|
+ str += 2;
|
||||||
|
}
|
||||||
|
*strp = str;
|
||||||
|
return i;
|
||||||
|
--
|
||||||
|
2.5.0
|
||||||
|
|
265
0005-Use-less-memory-when-extending-packages.patch
Normal file
265
0005-Use-less-memory-when-extending-packages.patch
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
From d06562f7b70f6ceb7d52e717efd1963ce6e8ecf0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
Date: Mon, 29 Feb 2016 13:49:48 +0100
|
||||||
|
Subject: [PATCH 4/9] Use less memory when extending packages
|
||||||
|
|
||||||
|
Implement a hash instead of mis-using a string pool.
|
||||||
|
---
|
||||||
|
ext/repo_rpmmd.c | 166 +++++++++++++++++++++++++++++++++++++++++--------------
|
||||||
|
1 file changed, 126 insertions(+), 40 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ext/repo_rpmmd.c b/ext/repo_rpmmd.c
|
||||||
|
index cc54b3e..77366c2 100644
|
||||||
|
--- a/ext/repo_rpmmd.c
|
||||||
|
+++ b/ext/repo_rpmmd.c
|
||||||
|
@@ -264,12 +264,12 @@ struct parsedata {
|
||||||
|
int first;
|
||||||
|
/* cspool ok to use */
|
||||||
|
int cshash_filled;
|
||||||
|
- /* Hash to maps checksums to solv */
|
||||||
|
- Stringpool cspool;
|
||||||
|
- /* Cache of known checksums to solvable id */
|
||||||
|
- Id *cshash;
|
||||||
|
- /* the current longest index in the table */
|
||||||
|
- int ncshash;
|
||||||
|
+
|
||||||
|
+ Hashtable cshash; /* checksum hash -> offset into csdata */
|
||||||
|
+ Hashval cshashm; /* hash mask */
|
||||||
|
+ int ncshash; /* entries used */
|
||||||
|
+ unsigned char *csdata; /* [len, checksum, id] */
|
||||||
|
+ int ncsdata; /* used bytes */
|
||||||
|
};
|
||||||
|
|
||||||
|
static Id
|
||||||
|
@@ -582,45 +582,125 @@ set_description_author(Repodata *data, Id handle, char *str, struct parsedata *p
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+/*-----------------------------------------------*/
|
||||||
|
+/* checksum hash functions
|
||||||
|
+ *
|
||||||
|
+ * used to look up a solvable with the checksum for solvable extension purposes.
|
||||||
|
+ *
|
||||||
|
+ */
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_cshash(struct parsedata *pd)
|
||||||
|
{
|
||||||
|
- /* initialize the string pool where we will store
|
||||||
|
- the package checksums we know about, to get an Id
|
||||||
|
- we can use in a cache */
|
||||||
|
- stringpool_init_empty(&pd->cspool);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_cshash(struct parsedata *pd)
|
||||||
|
{
|
||||||
|
- stringpool_free(&pd->cspool);
|
||||||
|
+ pd->cshash = solv_free(pd->cshash);
|
||||||
|
+ pd->ncshash = 0;
|
||||||
|
+ pd->cshashm = 0;
|
||||||
|
+ pd->csdata = solv_free(pd->csdata);
|
||||||
|
+ pd->ncsdata = 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline Hashval
|
||||||
|
+hashkey(const unsigned char *key, int keyl)
|
||||||
|
+{
|
||||||
|
+ return key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3];
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+rebuild_cshash(struct parsedata *pd)
|
||||||
|
+{
|
||||||
|
+ Hashval h, hh, hm;
|
||||||
|
+ Hashtable ht;
|
||||||
|
+ unsigned char *d, *de;
|
||||||
|
+
|
||||||
|
+ hm = pd->cshashm;
|
||||||
|
+#if 0
|
||||||
|
+ fprintf(stderr, "rebuild cshash with mask 0x%x\n", hm);
|
||||||
|
+#endif
|
||||||
|
solv_free(pd->cshash);
|
||||||
|
+ ht = pd->cshash = (Hashtable)solv_calloc(hm + 1, sizeof(Id));
|
||||||
|
+ d = pd->csdata;
|
||||||
|
+ de = d + pd->ncsdata;
|
||||||
|
+ while (d != de)
|
||||||
|
+ {
|
||||||
|
+ h = hashkey(d + 1, d[0] + 1) & hm;
|
||||||
|
+ hh = HASHCHAIN_START;
|
||||||
|
+ while (ht[h])
|
||||||
|
+ h = HASHCHAIN_NEXT(h, hh, hm);
|
||||||
|
+ ht[h] = d + 1 - pd->csdata;
|
||||||
|
+ d += 2 + d[0] + sizeof(Id);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* save the checksum as key to solvable id relationship for
|
||||||
|
- metadata extension */
|
||||||
|
static void
|
||||||
|
-put_in_cshash(struct parsedata *pd, const char *key, Id id)
|
||||||
|
+put_in_cshash(struct parsedata *pd, const unsigned char *key, int keyl, Id id)
|
||||||
|
{
|
||||||
|
- Id index = stringpool_str2id(&pd->cspool, key, 1);
|
||||||
|
- if (index >= pd->ncshash)
|
||||||
|
+ Hashtable ht;
|
||||||
|
+ Hashval h, hh, hm;
|
||||||
|
+ unsigned char *d;
|
||||||
|
+
|
||||||
|
+ if (keyl < 4 || keyl > 256)
|
||||||
|
+ return;
|
||||||
|
+ ht = pd->cshash;
|
||||||
|
+ hm = pd->cshashm;
|
||||||
|
+ h = hashkey(key, keyl) & hm;
|
||||||
|
+ hh = HASHCHAIN_START;
|
||||||
|
+ if (ht)
|
||||||
|
{
|
||||||
|
- pd->cshash = solv_zextend(pd->cshash, pd->ncshash, index + 1 - pd->ncshash, sizeof(Id), 255);
|
||||||
|
- pd->ncshash = index + 1;
|
||||||
|
+ while (ht[h])
|
||||||
|
+ {
|
||||||
|
+ unsigned char *d = pd->csdata + ht[h];
|
||||||
|
+ if (d[-1] == keyl && !memcmp(key, d, keyl))
|
||||||
|
+ return; /* XXX: first id wins... */
|
||||||
|
+ h = HASHCHAIN_NEXT(h, hh, hm);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
- /* add the checksum to the cache */
|
||||||
|
- pd->cshash[index] = id;
|
||||||
|
+ /* a new entry. put in csdata */
|
||||||
|
+ pd->csdata = solv_extend(pd->csdata, pd->ncsdata, 1, 1 + keyl + sizeof(Id), 4095);
|
||||||
|
+ d = pd->csdata + pd->ncsdata;
|
||||||
|
+ d[0] = keyl - 1;
|
||||||
|
+ memcpy(d + 1, key, keyl);
|
||||||
|
+ memcpy(d + 1 + keyl, &id, sizeof(Id));
|
||||||
|
+ pd->ncsdata += 1 + keyl + sizeof(Id);
|
||||||
|
+ if ((Hashval)++pd->ncshash * 2 > hm)
|
||||||
|
+ {
|
||||||
|
+ pd->cshashm = pd->cshashm ? (2 * pd->cshashm + 1) : 4095;
|
||||||
|
+ rebuild_cshash(pd);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ ht[h] = pd->ncsdata - (keyl + sizeof(Id));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Id
|
||||||
|
-lookup_cshash(struct parsedata *pd, const char *key)
|
||||||
|
+lookup_cshash(struct parsedata *pd, const unsigned char *key, int keyl)
|
||||||
|
{
|
||||||
|
- Id index = stringpool_str2id(&pd->cspool, key, 0);
|
||||||
|
- if (!index || index >= pd->ncshash || !pd->cshash[index])
|
||||||
|
+ Hashtable ht;
|
||||||
|
+ Hashval h, hh, hm;
|
||||||
|
+
|
||||||
|
+ if (keyl < 4 || keyl > 256)
|
||||||
|
+ return 0;
|
||||||
|
+ ht = pd->cshash;
|
||||||
|
+ if (!ht)
|
||||||
|
return 0;
|
||||||
|
- return pd->cshash[index];
|
||||||
|
+ hm = pd->cshashm;
|
||||||
|
+ h = hashkey(key, keyl) & hm;
|
||||||
|
+ hh = HASHCHAIN_START;
|
||||||
|
+ while (ht[h])
|
||||||
|
+ {
|
||||||
|
+ unsigned char *d = pd->csdata + ht[h];
|
||||||
|
+ if (d[-1] == keyl - 1 && !memcmp(key, d, keyl))
|
||||||
|
+ {
|
||||||
|
+ Id id;
|
||||||
|
+ memcpy(&id, d + keyl, sizeof(Id));
|
||||||
|
+ return id;
|
||||||
|
+ }
|
||||||
|
+ h = HASHCHAIN_NEXT(h, hh, hm);
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -630,14 +710,7 @@ fill_cshash_from_repo(struct parsedata *pd)
|
||||||
|
/* setup join data */
|
||||||
|
dataiterator_init(&di, pd->pool, pd->repo, 0, SOLVABLE_CHECKSUM, 0, 0);
|
||||||
|
while (dataiterator_step(&di))
|
||||||
|
- {
|
||||||
|
- const char *str;
|
||||||
|
-
|
||||||
|
- if (!solv_chksum_len(di.key->type))
|
||||||
|
- continue;
|
||||||
|
- str = repodata_chk2str(di.data, di.key->type, (const unsigned char *)di.kv.str);
|
||||||
|
- put_in_cshash(pd, str, di.solvid);
|
||||||
|
- }
|
||||||
|
+ put_in_cshash(pd, (const unsigned char *)di.kv.str, solv_chksum_len(di.key->type), di.solvid);
|
||||||
|
dataiterator_free(&di);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -645,7 +718,7 @@ static void
|
||||||
|
fill_cshash_from_new_solvables(struct parsedata *pd)
|
||||||
|
{
|
||||||
|
Pool *pool = pd->pool;
|
||||||
|
- Id cstype;
|
||||||
|
+ Id cstype = 0;
|
||||||
|
unsigned const char *cs;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
@@ -655,7 +728,7 @@ fill_cshash_from_new_solvables(struct parsedata *pd)
|
||||||
|
continue;
|
||||||
|
cs = repodata_lookup_bin_checksum_uninternalized(pd->data, i, SOLVABLE_CHECKSUM, &cstype);
|
||||||
|
if (cs)
|
||||||
|
- put_in_cshash(pd, repodata_chk2str(pd->data, cstype, cs), i);
|
||||||
|
+ put_in_cshash(pd, cs, solv_chksum_len(cstype), i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -750,13 +823,23 @@ startElement(void *userData, const char *name, const char **atts)
|
||||||
|
pd->extending = 0;
|
||||||
|
if ((pkgid = find_attr("pkgid", atts)) != NULL)
|
||||||
|
{
|
||||||
|
+ unsigned char chk[256];
|
||||||
|
+ int l;
|
||||||
|
+ const char *str = pkgid;
|
||||||
|
if (!pd->cshash_filled)
|
||||||
|
{
|
||||||
|
pd->cshash_filled = 1;
|
||||||
|
fill_cshash_from_new_solvables(pd);
|
||||||
|
}
|
||||||
|
+ handle = 0;
|
||||||
|
+ /* convert into bin checksum */
|
||||||
|
+ l = solv_hex2bin(&str, chk, sizeof(chk));
|
||||||
|
/* look at the checksum cache */
|
||||||
|
- handle = lookup_cshash(pd, pkgid);
|
||||||
|
+ if (l >= 4 && !pkgid[2 * l])
|
||||||
|
+ handle = lookup_cshash(pd, chk, l);
|
||||||
|
+#if 0
|
||||||
|
+ fprintf(stderr, "Lookup %s -> %d\n", pkgid, handle);
|
||||||
|
+#endif
|
||||||
|
if (!handle)
|
||||||
|
{
|
||||||
|
pool_debug(pool, SOLV_WARN, "the repository specifies extra information about package with checksum '%s', which does not exist in the repository.\n", pkgid);
|
||||||
|
@@ -1056,17 +1139,20 @@ endElement(void *userData, const char *name)
|
||||||
|
break;
|
||||||
|
case STATE_CHECKSUM:
|
||||||
|
{
|
||||||
|
- if (!pd->chksumtype)
|
||||||
|
+ unsigned char chk[256];
|
||||||
|
+ int l = solv_chksum_len(pd->chksumtype);
|
||||||
|
+ const char *str = pd->content;
|
||||||
|
+ if (!l || l > sizeof(chk))
|
||||||
|
break;
|
||||||
|
- if (strlen(pd->content) != 2 * solv_chksum_len(pd->chksumtype))
|
||||||
|
+ if (solv_hex2bin(&str, chk, l) != l || pd->content[2 * l])
|
||||||
|
{
|
||||||
|
- pd->ret = pool_error(pool, -1, "line %d: invalid checksum length for %s", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), solv_chksum_type2str(pd->chksumtype));
|
||||||
|
+ pd->ret = pool_error(pool, -1, "line %u: invalid %s checksum", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), solv_chksum_type2str(pd->chksumtype));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- repodata_set_checksum(pd->data, handle, SOLVABLE_CHECKSUM, pd->chksumtype, pd->content);
|
||||||
|
+ repodata_set_bin_checksum(pd->data, handle, SOLVABLE_CHECKSUM, pd->chksumtype, chk);
|
||||||
|
/* we save the checksum to solvable id relationship for extending metadata */
|
||||||
|
if (pd->cshash_filled)
|
||||||
|
- put_in_cshash(pd, pd->content, s - pool->solvables);
|
||||||
|
+ put_in_cshash(pd, chk, l, s - pool->solvables);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STATE_FILE:
|
||||||
|
--
|
||||||
|
2.5.0
|
||||||
|
|
30
0006-Fix-comments.patch
Normal file
30
0006-Fix-comments.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From 4bcff7d8e7fadcc0b314aa654ce97579db3bbe1a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
Date: Mon, 29 Feb 2016 14:14:05 +0100
|
||||||
|
Subject: [PATCH 5/9] Fix comments
|
||||||
|
|
||||||
|
---
|
||||||
|
ext/repo_rpmmd.c | 7 ++-----
|
||||||
|
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ext/repo_rpmmd.c b/ext/repo_rpmmd.c
|
||||||
|
index 77366c2..5ef5c25 100644
|
||||||
|
--- a/ext/repo_rpmmd.c
|
||||||
|
+++ b/ext/repo_rpmmd.c
|
||||||
|
@@ -259,11 +259,8 @@ struct parsedata {
|
||||||
|
Id changelog_handle;
|
||||||
|
|
||||||
|
int extending; /* are we extending an existing solvable? */
|
||||||
|
-
|
||||||
|
- /* first solvable we added */
|
||||||
|
- int first;
|
||||||
|
- /* cspool ok to use */
|
||||||
|
- int cshash_filled;
|
||||||
|
+ int first; /* first solvable we added */
|
||||||
|
+ int cshash_filled; /* hash is filled with data */
|
||||||
|
|
||||||
|
Hashtable cshash; /* checksum hash -> offset into csdata */
|
||||||
|
Hashval cshashm; /* hash mask */
|
||||||
|
--
|
||||||
|
2.5.0
|
||||||
|
|
@ -0,0 +1,50 @@
|
|||||||
|
From 5218114520e47f50bef59606d32d9434ee4b6f47 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
Date: Thu, 3 Mar 2016 12:59:18 +0100
|
||||||
|
Subject: [PATCH 6/9] rpmmd diskusage: prepend a '/' to the dir if not already
|
||||||
|
there
|
||||||
|
|
||||||
|
Makes the code consistent with repo_susetags.
|
||||||
|
---
|
||||||
|
ext/repo_rpmmd.c | 23 ++++++++++++++++-------
|
||||||
|
1 file changed, 16 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ext/repo_rpmmd.c b/ext/repo_rpmmd.c
|
||||||
|
index 5ef5c25..78264cc 100644
|
||||||
|
--- a/ext/repo_rpmmd.c
|
||||||
|
+++ b/ext/repo_rpmmd.c
|
||||||
|
@@ -1014,15 +1014,24 @@ startElement(void *userData, const char *name, const char **atts)
|
||||||
|
{
|
||||||
|
long filesz = 0, filenum = 0;
|
||||||
|
Id dirid;
|
||||||
|
- if ((str = find_attr("name", atts)) != 0)
|
||||||
|
- dirid = repodata_str2dir(pd->data, str, 1);
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
+ if ((str = find_attr("name", atts)) == 0)
|
||||||
|
+ {
|
||||||
|
pd->ret = pool_error(pool, -1, "<dir .../> tag without 'name' attribute");
|
||||||
|
break;
|
||||||
|
- }
|
||||||
|
- if (!dirid)
|
||||||
|
- dirid = repodata_str2dir(pd->data, "/", 1);
|
||||||
|
+ }
|
||||||
|
+ if (*str != '/')
|
||||||
|
+ {
|
||||||
|
+ int l = strlen(str) + 2;
|
||||||
|
+ if (l > pd->acontent)
|
||||||
|
+ {
|
||||||
|
+ pd->content = solv_realloc(pd->content, l + 256);
|
||||||
|
+ pd->acontent = l + 256;
|
||||||
|
+ }
|
||||||
|
+ *pd->content = '/';
|
||||||
|
+ strcpy(pd->content + 1, str);
|
||||||
|
+ str = pd->content;
|
||||||
|
+ }
|
||||||
|
+ dirid = repodata_str2dir(pd->data, str, 1);
|
||||||
|
if ((str = find_attr("size", atts)) != 0)
|
||||||
|
filesz = strtol(str, 0, 0);
|
||||||
|
if ((str = find_attr("count", atts)) != 0)
|
||||||
|
--
|
||||||
|
2.5.0
|
||||||
|
|
1465
0008-Split-diskusage-and-fileprovides-code-into-separate-.patch
Normal file
1465
0008-Split-diskusage-and-fileprovides-code-into-separate-.patch
Normal file
File diff suppressed because it is too large
Load Diff
47
0009-Make-_Pool_tmpspace-definition-internal.patch
Normal file
47
0009-Make-_Pool_tmpspace-definition-internal.patch
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
From e1f29013dd6eeb77db7fb0ad6e9343cd880ccbde Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
Date: Thu, 3 Mar 2016 15:18:34 +0100
|
||||||
|
Subject: [PATCH 8/9] Make _Pool_tmpspace definition internal
|
||||||
|
|
||||||
|
---
|
||||||
|
src/pool.h | 11 ++++++++---
|
||||||
|
1 file changed, 8 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/pool.h b/src/pool.h
|
||||||
|
index 4a2089d..b9e2ed6 100644
|
||||||
|
--- a/src/pool.h
|
||||||
|
+++ b/src/pool.h
|
||||||
|
@@ -34,9 +34,6 @@ extern "C" {
|
||||||
|
#define SYSTEMSOLVABLE 1
|
||||||
|
|
||||||
|
|
||||||
|
-/* how many strings to maintain (round robin) */
|
||||||
|
-#define POOL_TMPSPACEBUF 16
|
||||||
|
-
|
||||||
|
/*----------------------------------------------- */
|
||||||
|
|
||||||
|
struct _Repo;
|
||||||
|
@@ -52,12 +49,20 @@ typedef struct _Datapos {
|
||||||
|
Id dp;
|
||||||
|
} Datapos;
|
||||||
|
|
||||||
|
+
|
||||||
|
+#ifdef LIBSOLV_INTERNAL
|
||||||
|
+
|
||||||
|
+/* how many strings to maintain (round robin) */
|
||||||
|
+#define POOL_TMPSPACEBUF 16
|
||||||
|
+
|
||||||
|
struct _Pool_tmpspace {
|
||||||
|
char *buf[POOL_TMPSPACEBUF];
|
||||||
|
int len[POOL_TMPSPACEBUF];
|
||||||
|
int n;
|
||||||
|
};
|
||||||
|
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
struct _Pool {
|
||||||
|
void *appdata; /* application private pointer */
|
||||||
|
|
||||||
|
--
|
||||||
|
2.5.0
|
||||||
|
|
311
0010-Rework-orphan-handling-in-dup-mode.patch
Normal file
311
0010-Rework-orphan-handling-in-dup-mode.patch
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
From 6c9cef4ef810cd32ffeee20986a16e0871fc0bae Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
Date: Mon, 7 Mar 2016 14:09:40 +0100
|
||||||
|
Subject: [PATCH 9/9] Rework orphan handling in dup mode
|
||||||
|
|
||||||
|
The old code had problems when the updaters contained other
|
||||||
|
installed packages.
|
||||||
|
---
|
||||||
|
src/rules.c | 193 +++++++++++++++++++++++++++++++++++++++++++----------------
|
||||||
|
src/rules.h | 3 +-
|
||||||
|
src/solver.c | 7 ++-
|
||||||
|
3 files changed, 149 insertions(+), 54 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/rules.c b/src/rules.c
|
||||||
|
index 4cd53d3..0e2c955 100644
|
||||||
|
--- a/src/rules.c
|
||||||
|
+++ b/src/rules.c
|
||||||
|
@@ -1170,35 +1170,56 @@ solver_addpkgrulesforupdaters(Solver *solv, Solvable *s, Map *m, int allow_all)
|
||||||
|
***
|
||||||
|
***/
|
||||||
|
|
||||||
|
+static int
|
||||||
|
+dup_maykeepinstalled(Solver *solv, Solvable *s)
|
||||||
|
+{
|
||||||
|
+ Pool *pool = solv->pool;
|
||||||
|
+ Id ip, pp;
|
||||||
|
+
|
||||||
|
+ if (solv->dupmap.size && MAPTST(&solv->dupmap, s - pool->solvables))
|
||||||
|
+ return 1;
|
||||||
|
+ /* is installed identical to a good one? */
|
||||||
|
+ FOR_PROVIDES(ip, pp, s->name)
|
||||||
|
+ {
|
||||||
|
+ Solvable *is = pool->solvables + ip;
|
||||||
|
+ if (is->evr != s->evr)
|
||||||
|
+ continue;
|
||||||
|
+ if (solv->dupmap.size)
|
||||||
|
+ {
|
||||||
|
+ if (!MAPTST(&solv->dupmap, ip))
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ else if (is->repo == pool->installed)
|
||||||
|
+ continue;
|
||||||
|
+ if (solvable_identical(s, is))
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
static Id
|
||||||
|
-finddistupgradepackages(Solver *solv, Solvable *s, Queue *qs, int allow_all)
|
||||||
|
+finddistupgradepackages(Solver *solv, Solvable *s, Queue *qs)
|
||||||
|
{
|
||||||
|
Pool *pool = solv->pool;
|
||||||
|
- int i;
|
||||||
|
+ int i, j;
|
||||||
|
|
||||||
|
- policy_findupdatepackages(solv, s, qs, allow_all ? allow_all : 2);
|
||||||
|
- if (!qs->count)
|
||||||
|
+ policy_findupdatepackages(solv, s, qs, 2);
|
||||||
|
+ if (qs->count)
|
||||||
|
{
|
||||||
|
- if (allow_all)
|
||||||
|
- return 0; /* orphaned, don't create feature rule */
|
||||||
|
- /* check if this is an orphaned package */
|
||||||
|
- policy_findupdatepackages(solv, s, qs, 1);
|
||||||
|
- if (!qs->count)
|
||||||
|
- return 0; /* orphaned, don't create update rule */
|
||||||
|
- qs->count = 0;
|
||||||
|
- return -SYSTEMSOLVABLE; /* supported but not installable */
|
||||||
|
+ /* remove installed packages we can't keep */
|
||||||
|
+ for (i = j = 0; i < qs->count; i++)
|
||||||
|
+ {
|
||||||
|
+ Solvable *ns = pool->solvables + qs->elements[i];
|
||||||
|
+ if (ns->repo == pool->installed && !dup_maykeepinstalled(solv, ns))
|
||||||
|
+ continue;
|
||||||
|
+ qs->elements[j++] = qs->elements[i];
|
||||||
|
+ }
|
||||||
|
+ queue_truncate(qs, j);
|
||||||
|
}
|
||||||
|
- if (allow_all)
|
||||||
|
- return s - pool->solvables;
|
||||||
|
/* check if it is ok to keep the installed package */
|
||||||
|
- if (solv->dupmap.size && MAPTST(&solv->dupmap, s - pool->solvables))
|
||||||
|
+ if (dup_maykeepinstalled(solv, s))
|
||||||
|
return s - pool->solvables;
|
||||||
|
- for (i = 0; i < qs->count; i++)
|
||||||
|
- {
|
||||||
|
- Solvable *ns = pool->solvables + qs->elements[i];
|
||||||
|
- if (s->evr == ns->evr && solvable_identical(s, ns))
|
||||||
|
- return s - pool->solvables;
|
||||||
|
- }
|
||||||
|
/* nope, it must be some other package */
|
||||||
|
return -SYSTEMSOLVABLE;
|
||||||
|
}
|
||||||
|
@@ -1240,6 +1261,73 @@ set_specialupdaters(Solver *solv, Solvable *s, Id d)
|
||||||
|
solv->specialupdaters[s - solv->pool->solvables - installed->start] = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef ENABLE_LINKED_PKGS
|
||||||
|
+/* Check if this is a linked pseudo package. As it is linked, we do not need an update/feature rule */
|
||||||
|
+static inline int
|
||||||
|
+is_linked_pseudo_package(Solver *solv, Solvable *s)
|
||||||
|
+{
|
||||||
|
+ Pool *pool = solv->pool;
|
||||||
|
+ if (solv->instbuddy && solv->instbuddy[s - pool->solvables - solv->installed->start])
|
||||||
|
+ {
|
||||||
|
+ const char *name = pool_id2str(pool, s->name);
|
||||||
|
+ if (strncmp(name, "pattern:", 8) == 0 || strncmp(name, "application:", 12) == 0)
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+solver_addfeaturerule(Solver *solv, Solvable *s)
|
||||||
|
+{
|
||||||
|
+ Pool *pool = solv->pool;
|
||||||
|
+ int i;
|
||||||
|
+ Id p;
|
||||||
|
+ Queue qs;
|
||||||
|
+ Id qsbuf[64];
|
||||||
|
+
|
||||||
|
+#ifdef ENABLE_LINKED_PKGS
|
||||||
|
+ if (is_linked_pseudo_package(solv, s))
|
||||||
|
+ {
|
||||||
|
+ solver_addrule(solv, 0, 0, 0); /* no feature rules for those */
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+ queue_init_buffer(&qs, qsbuf, sizeof(qsbuf)/sizeof(*qsbuf));
|
||||||
|
+ p = s - pool->solvables;
|
||||||
|
+ policy_findupdatepackages(solv, s, &qs, 1);
|
||||||
|
+ if (solv->dupmap_all || (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p)))
|
||||||
|
+ {
|
||||||
|
+ if (!dup_maykeepinstalled(solv, s))
|
||||||
|
+ {
|
||||||
|
+ for (i = 0; i < qs.count; i++)
|
||||||
|
+ {
|
||||||
|
+ Solvable *ns = pool->solvables + qs.elements[i];
|
||||||
|
+ if (ns->repo != pool->installed || dup_maykeepinstalled(solv, ns))
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (i == qs.count)
|
||||||
|
+ {
|
||||||
|
+ solver_addrule(solv, 0, 0, 0); /* this is an orphan */
|
||||||
|
+ queue_free(&qs);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (qs.count > 1)
|
||||||
|
+ {
|
||||||
|
+ Id d = pool_queuetowhatprovides(pool, &qs);
|
||||||
|
+ queue_free(&qs);
|
||||||
|
+ solver_addrule(solv, p, 0, d); /* allow update of s */
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ Id d = qs.count ? qs.elements[0] : 0;
|
||||||
|
+ queue_free(&qs);
|
||||||
|
+ solver_addrule(solv, p, d, 0); /* allow update of s */
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*-------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* add rule for update
|
||||||
|
@@ -1249,7 +1337,7 @@ set_specialupdaters(Solver *solv, Solvable *s, Id d)
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
-solver_addupdaterule(Solver *solv, Solvable *s, int allow_all)
|
||||||
|
+solver_addupdaterule(Solver *solv, Solvable *s)
|
||||||
|
{
|
||||||
|
/* installed packages get a special upgrade allowed rule */
|
||||||
|
Pool *pool = solv->pool;
|
||||||
|
@@ -1257,48 +1345,53 @@ solver_addupdaterule(Solver *solv, Solvable *s, int allow_all)
|
||||||
|
Queue qs;
|
||||||
|
Id qsbuf[64];
|
||||||
|
int isorphaned = 0;
|
||||||
|
+ Rule *r;
|
||||||
|
+ int islinkedpseudo = 0;
|
||||||
|
|
||||||
|
- queue_init_buffer(&qs, qsbuf, sizeof(qsbuf)/sizeof(*qsbuf));
|
||||||
|
p = s - pool->solvables;
|
||||||
|
+#ifdef ENABLE_LINKED_PKGS
|
||||||
|
+ islinkedpseudo = is_linked_pseudo_package(solv, s);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ /* Orphan detection. We cheat by looking at the feature rule, which
|
||||||
|
+ * we already calculated */
|
||||||
|
+ r = solv->rules + solv->featurerules + (p - solv->installed->start);
|
||||||
|
+ if (!r->p && !islinkedpseudo)
|
||||||
|
+ {
|
||||||
|
+ p = 0;
|
||||||
|
+ queue_push(&solv->orphaned, s - pool->solvables); /* an orphaned package */
|
||||||
|
+ if (solv->keep_orphans && !(solv->droporphanedmap_all || (solv->droporphanedmap.size && MAPTST(&solv->droporphanedmap, s - pool->solvables - solv->installed->start))))
|
||||||
|
+ p = s - pool->solvables; /* keep this orphaned package installed */
|
||||||
|
+ solver_addrule(solv, p, 0, 0);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ queue_init_buffer(&qs, qsbuf, sizeof(qsbuf)/sizeof(*qsbuf));
|
||||||
|
/* find update candidates for 's' */
|
||||||
|
if (solv->dupmap_all || (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p)))
|
||||||
|
- p = finddistupgradepackages(solv, s, &qs, allow_all);
|
||||||
|
+ p = finddistupgradepackages(solv, s, &qs);
|
||||||
|
else
|
||||||
|
- policy_findupdatepackages(solv, s, &qs, allow_all);
|
||||||
|
+ policy_findupdatepackages(solv, s, &qs, 0);
|
||||||
|
|
||||||
|
#ifdef ENABLE_LINKED_PKGS
|
||||||
|
- if (solv->instbuddy && solv->instbuddy[s - pool->solvables - solv->installed->start])
|
||||||
|
+ if (islinkedpseudo)
|
||||||
|
{
|
||||||
|
- const char *name = pool_id2str(pool, s->name);
|
||||||
|
- if (strncmp(name, "pattern:", 8) == 0 || strncmp(name, "application:", 12) == 0)
|
||||||
|
+ /* a linked pseudo package. As it is linked, we do not need an update/feature rule */
|
||||||
|
+ /* nevertheless we set specialupdaters so we can update */
|
||||||
|
+ solver_addrule(solv, 0, 0, 0);
|
||||||
|
+ if (qs.count)
|
||||||
|
{
|
||||||
|
- /* a linked pseudo package. As it is linked, we do not need an update/feature rule */
|
||||||
|
- /* nevertheless we set specialupdaters so we can update */
|
||||||
|
- solver_addrule(solv, 0, 0, 0);
|
||||||
|
- if (!allow_all && qs.count)
|
||||||
|
- {
|
||||||
|
- if (p != -SYSTEMSOLVABLE)
|
||||||
|
- queue_unshift(&qs, p);
|
||||||
|
- if (qs.count)
|
||||||
|
- set_specialupdaters(solv, s, pool_queuetowhatprovides(pool, &qs));
|
||||||
|
- }
|
||||||
|
- queue_free(&qs);
|
||||||
|
- return;
|
||||||
|
+ if (p != -SYSTEMSOLVABLE)
|
||||||
|
+ queue_unshift(&qs, p);
|
||||||
|
+ if (qs.count)
|
||||||
|
+ set_specialupdaters(solv, s, pool_queuetowhatprovides(pool, &qs));
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
- if (!allow_all && !p) /* !p implies qs.count == 0 */
|
||||||
|
- {
|
||||||
|
- queue_push(&solv->orphaned, s - pool->solvables); /* an orphaned package */
|
||||||
|
- if (solv->keep_orphans && !(solv->droporphanedmap_all || (solv->droporphanedmap.size && MAPTST(&solv->droporphanedmap, s - pool->solvables - solv->installed->start))))
|
||||||
|
- p = s - pool->solvables; /* keep this orphaned package installed */
|
||||||
|
queue_free(&qs);
|
||||||
|
- solver_addrule(solv, p, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
- if (!allow_all && qs.count && solv->multiversion.size)
|
||||||
|
+ if (qs.count && solv->multiversion.size)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
diff --git a/src/rules.h b/src/rules.h
|
||||||
|
index 606819b..29325ea 100644
|
||||||
|
--- a/src/rules.h
|
||||||
|
+++ b/src/rules.h
|
||||||
|
@@ -111,7 +111,8 @@ extern void solver_addpkgrulesforlinked(struct _Solver *solv, Map *m);
|
||||||
|
extern void solver_addpkgrulesforupdaters(struct _Solver *solv, Solvable *s, Map *m, int allow_all);
|
||||||
|
|
||||||
|
/* update/feature rules */
|
||||||
|
-extern void solver_addupdaterule(struct _Solver *solv, Solvable *s, int allow_all);
|
||||||
|
+extern void solver_addfeaturerule(struct _Solver *solv, Solvable *s);
|
||||||
|
+extern void solver_addupdaterule(struct _Solver *solv, Solvable *s);
|
||||||
|
|
||||||
|
/* infarch rules */
|
||||||
|
extern void solver_addinfarchrules(struct _Solver *solv, Map *addedmap);
|
||||||
|
diff --git a/src/solver.c b/src/solver.c
|
||||||
|
index 261f367..15a3114 100644
|
||||||
|
--- a/src/solver.c
|
||||||
|
+++ b/src/solver.c
|
||||||
|
@@ -3716,7 +3716,7 @@ solver_solve(Solver *solv, Queue *job)
|
||||||
|
solver_addrule(solv, 0, 0, 0); /* create dummy rule */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
- solver_addupdaterule(solv, s, 1); /* allow s to be updated */
|
||||||
|
+ solver_addfeaturerule(solv, s);
|
||||||
|
}
|
||||||
|
/* make sure we accounted for all rules */
|
||||||
|
assert(solv->nrules - solv->featurerules == installed->end - installed->start);
|
||||||
|
@@ -3744,7 +3744,7 @@ solver_solve(Solver *solv, Queue *job)
|
||||||
|
solver_addrule(solv, 0, 0, 0); /* create dummy rule */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
- solver_addupdaterule(solv, s, 0); /* allowall = 0: downgrades not allowed */
|
||||||
|
+ solver_addupdaterule(solv, s);
|
||||||
|
/*
|
||||||
|
* check for and remove duplicate
|
||||||
|
*/
|
||||||
|
@@ -3759,9 +3759,10 @@ solver_solve(Solver *solv, Queue *job)
|
||||||
|
/* it's also orphaned if the feature rule consists just of the installed package */
|
||||||
|
if (!solv->dupmap_all && sr->p == i && !sr->d && !sr->w2)
|
||||||
|
queue_push(&solv->orphaned, i);
|
||||||
|
+
|
||||||
|
if (!solver_rulecmp(solv, r, sr))
|
||||||
|
memset(sr, 0, sizeof(*sr)); /* delete unneeded feature rule */
|
||||||
|
- else
|
||||||
|
+ else if (sr->p)
|
||||||
|
solver_disablerule(solv, sr); /* disable feature rule for now */
|
||||||
|
}
|
||||||
|
/* consistency check: we added a rule for _every_ installed solvable */
|
||||||
|
--
|
||||||
|
2.5.0
|
||||||
|
|
14
libsolv.spec
14
libsolv.spec
@ -30,11 +30,20 @@
|
|||||||
|
|
||||||
Name: libsolv
|
Name: libsolv
|
||||||
Version: 0.6.19
|
Version: 0.6.19
|
||||||
Release: 1%{?dist}
|
Release: 2%{?dist}
|
||||||
License: BSD
|
License: BSD
|
||||||
Url: https://github.com/openSUSE/libsolv
|
Url: https://github.com/openSUSE/libsolv
|
||||||
Source: https://github.com/openSUSE/libsolv/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz
|
Source: https://github.com/openSUSE/libsolv/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz
|
||||||
Patch0: 0001-ruby-make-compatible-with-ruby-2.2.patch
|
Patch0: 0001-ruby-make-compatible-with-ruby-2.2.patch
|
||||||
|
Patch1: 0002-Add-repodata_lookup_dirstrarray_uninternalized-metho.patch
|
||||||
|
Patch2: 0003-Do-not-create-a-checksum-hash-when-we-re-not-extendi.patch
|
||||||
|
Patch3: 0004-solv_hex2bin-don-t-eat-nibbles.patch
|
||||||
|
Patch4: 0005-Use-less-memory-when-extending-packages.patch
|
||||||
|
Patch5: 0006-Fix-comments.patch
|
||||||
|
Patch6: 0007-rpmmd-diskusage-prepend-a-to-the-dir-if-not-already-.patch
|
||||||
|
Patch7: 0008-Split-diskusage-and-fileprovides-code-into-separate-.patch
|
||||||
|
Patch8: 0009-Make-_Pool_tmpspace-definition-internal.patch
|
||||||
|
Patch9: 0010-Rework-orphan-handling-in-dup-mode.patch
|
||||||
|
|
||||||
Group: Development/Libraries
|
Group: Development/Libraries
|
||||||
Summary: Package dependency solver
|
Summary: Package dependency solver
|
||||||
@ -225,6 +234,9 @@ make ARGS="-V" test
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Mar 8 2016 Jaroslav Mracek <jmracek@redhat.com> - 0.6.19-2
|
||||||
|
- Apply 9 patches from upstream
|
||||||
|
|
||||||
* Sat Feb 27 2016 Igor Gnatenko <i.gnatenko.brain@gmail.com> - 0.6.19-1
|
* Sat Feb 27 2016 Igor Gnatenko <i.gnatenko.brain@gmail.com> - 0.6.19-1
|
||||||
- Update to 0.6.19
|
- Update to 0.6.19
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user