From 3be5091df898662f389f325f624740e5046e7ca0 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Sat, 9 Apr 2016 10:06:49 +0200 Subject: [PATCH] Update to 0.6.20 --- .gitignore | 1 + 0001-ruby-make-compatible-with-ruby-2.2.patch | 44 - ...kup_dirstrarray_uninternalized-metho.patch | 79 - ...checksum-hash-when-we-re-not-extendi.patch | 272 --- 0004-solv_hex2bin-don-t-eat-nibbles.patch | 34 - ...-less-memory-when-extending-packages.patch | 265 --- 0006-Fix-comments.patch | 30 - ...prepend-a-to-the-dir-if-not-already-.patch | 50 - ...and-fileprovides-code-into-separate-.patch | 1465 ----------------- ...e-_Pool_tmpspace-definition-internal.patch | 47 - 0010-Rework-orphan-handling-in-dup-mode.patch | 311 ---- libsolv.spec | 17 +- sources | 2 +- 13 files changed, 7 insertions(+), 2610 deletions(-) delete mode 100644 0001-ruby-make-compatible-with-ruby-2.2.patch delete mode 100644 0002-Add-repodata_lookup_dirstrarray_uninternalized-metho.patch delete mode 100644 0003-Do-not-create-a-checksum-hash-when-we-re-not-extendi.patch delete mode 100644 0004-solv_hex2bin-don-t-eat-nibbles.patch delete mode 100644 0005-Use-less-memory-when-extending-packages.patch delete mode 100644 0006-Fix-comments.patch delete mode 100644 0007-rpmmd-diskusage-prepend-a-to-the-dir-if-not-already-.patch delete mode 100644 0008-Split-diskusage-and-fileprovides-code-into-separate-.patch delete mode 100644 0009-Make-_Pool_tmpspace-definition-internal.patch delete mode 100644 0010-Rework-orphan-handling-in-dup-mode.patch diff --git a/.gitignore b/.gitignore index dc3f5b4..7742487 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ /libsolv-0.6.14.tar.gz /libsolv-0.6.15.tar.gz /libsolv-0.6.19.tar.gz +/libsolv-0.6.20.tar.gz diff --git a/0001-ruby-make-compatible-with-ruby-2.2.patch b/0001-ruby-make-compatible-with-ruby-2.2.patch deleted file mode 100644 index 51333aa..0000000 --- a/0001-ruby-make-compatible-with-ruby-2.2.patch +++ /dev/null @@ -1,44 +0,0 @@ -From d82a26ca0950191546f546264e79ff72e2dbf09f Mon Sep 17 00:00:00 2001 -From: Igor Gnatenko -Date: Mon, 12 Oct 2015 18:52:16 +0200 -Subject: [PATCH] ruby: make compatible with ruby 2.2 - -Signed-off-by: Igor Gnatenko ---- - bindings/ruby/CMakeLists.txt | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/bindings/ruby/CMakeLists.txt b/bindings/ruby/CMakeLists.txt -index 6c3bd50..a7a3394 100644 ---- a/bindings/ruby/CMakeLists.txt -+++ b/bindings/ruby/CMakeLists.txt -@@ -6,8 +6,17 @@ ELSE (USE_VENDORDIRS AND RUBY_VENDORARCH_DIR) - SET (RUBY_INSTALL_DIR ${RUBY_SITEARCH_DIR}) - ENDIF (USE_VENDORDIRS AND RUBY_VENDORARCH_DIR) - -+EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['arch']" -+ OUTPUT_VARIABLE RUBY_ARCH) -+ -+EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['rubyhdrdir']" -+ OUTPUT_VARIABLE RUBY_HDR_DIR) -+ -+SET(RUBY_INCLUDE_DIRS ${RUBY_HDR_DIR} ${RUBY_HDR_DIR}/${RUBY_ARCH}) -+ - MESSAGE (STATUS "Ruby executable: ${RUBY_EXECUTABLE}") - MESSAGE (STATUS "Ruby installation dir: ${RUBY_INSTALL_DIR}") -+MESSAGE (STATUS "Ruby include dir: ${RUBY_INCLUDE_DIRS}") - - ADD_CUSTOM_COMMAND ( - OUTPUT solv_ruby.c -@@ -17,7 +26,7 @@ ADD_CUSTOM_COMMAND ( - ) - - ADD_DEFINITIONS(-Wno-unused) --INCLUDE_DIRECTORIES (${RUBY_INCLUDE_PATH}) -+INCLUDE_DIRECTORIES (${RUBY_INCLUDE_DIRS}) - - ADD_LIBRARY (bindings_ruby MODULE solv_ruby.c) - SET_TARGET_PROPERTIES (bindings_ruby PROPERTIES PREFIX "" OUTPUT_NAME "solv") --- -2.6.1 - diff --git a/0002-Add-repodata_lookup_dirstrarray_uninternalized-metho.patch b/0002-Add-repodata_lookup_dirstrarray_uninternalized-metho.patch deleted file mode 100644 index d0fc869..0000000 --- a/0002-Add-repodata_lookup_dirstrarray_uninternalized-metho.patch +++ /dev/null @@ -1,79 +0,0 @@ -From f362259ac2f92c6c1914974032f2f7c436ac00d4 Mon Sep 17 00:00:00 2001 -From: Michael Schroeder -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 - diff --git a/0003-Do-not-create-a-checksum-hash-when-we-re-not-extendi.patch b/0003-Do-not-create-a-checksum-hash-when-we-re-not-extendi.patch deleted file mode 100644 index de4b9d7..0000000 --- a/0003-Do-not-create-a-checksum-hash-when-we-re-not-extendi.patch +++ /dev/null @@ -1,272 +0,0 @@ -From 0280a6a08344a11c8fd0e0226263cc8a808fd4c1 Mon Sep 17 00:00:00 2001 -From: Michael Schroeder -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 - diff --git a/0004-solv_hex2bin-don-t-eat-nibbles.patch b/0004-solv_hex2bin-don-t-eat-nibbles.patch deleted file mode 100644 index f027832..0000000 --- a/0004-solv_hex2bin-don-t-eat-nibbles.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 4cebb81db05fd9281a6d482adce25c93605ed5da Mon Sep 17 00:00:00 2001 -From: Michael Schroeder -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 - diff --git a/0005-Use-less-memory-when-extending-packages.patch b/0005-Use-less-memory-when-extending-packages.patch deleted file mode 100644 index f8eaa49..0000000 --- a/0005-Use-less-memory-when-extending-packages.patch +++ /dev/null @@ -1,265 +0,0 @@ -From d06562f7b70f6ceb7d52e717efd1963ce6e8ecf0 Mon Sep 17 00:00:00 2001 -From: Michael Schroeder -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 - diff --git a/0006-Fix-comments.patch b/0006-Fix-comments.patch deleted file mode 100644 index 97b7352..0000000 --- a/0006-Fix-comments.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 4bcff7d8e7fadcc0b314aa654ce97579db3bbe1a Mon Sep 17 00:00:00 2001 -From: Michael Schroeder -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 - diff --git a/0007-rpmmd-diskusage-prepend-a-to-the-dir-if-not-already-.patch b/0007-rpmmd-diskusage-prepend-a-to-the-dir-if-not-already-.patch deleted file mode 100644 index 40a13cf..0000000 --- a/0007-rpmmd-diskusage-prepend-a-to-the-dir-if-not-already-.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 5218114520e47f50bef59606d32d9434ee4b6f47 Mon Sep 17 00:00:00 2001 -From: Michael Schroeder -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, " 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 - diff --git a/0008-Split-diskusage-and-fileprovides-code-into-separate-.patch b/0008-Split-diskusage-and-fileprovides-code-into-separate-.patch deleted file mode 100644 index 195b5a6..0000000 --- a/0008-Split-diskusage-and-fileprovides-code-into-separate-.patch +++ /dev/null @@ -1,1465 +0,0 @@ -From e77926c355afff8be62e401ff3c4446fcbaaace5 Mon Sep 17 00:00:00 2001 -From: Michael Schroeder -Date: Thu, 3 Mar 2016 15:08:38 +0100 -Subject: [PATCH 7/9] Split diskusage and fileprovides code into separate files - ---- - src/CMakeLists.txt | 3 +- - src/diskusage.c | 348 +++++++++++++++++++++++++++ - src/fileprovides.c | 373 +++++++++++++++++++++++++++++ - src/pool.c | 676 ----------------------------------------------------- - 4 files changed, 723 insertions(+), 677 deletions(-) - create mode 100644 src/diskusage.c - create mode 100644 src/fileprovides.c - -diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt -index a2c0098..241890d 100644 ---- a/src/CMakeLists.txt -+++ b/src/CMakeLists.txt -@@ -18,7 +18,8 @@ SET (libsolv_SRCS - solver.c solverdebug.c repo_solv.c repo_write.c evr.c pool.c - queue.c repo.c repodata.c repopage.c util.c policy.c solvable.c - transaction.c order.c rules.c problems.c linkedpkg.c cplxdeps.c -- chksum.c md5.c sha1.c sha2.c solvversion.c selection.c) -+ chksum.c md5.c sha1.c sha2.c solvversion.c selection.c -+ fileprovides.c diskusage.c) - - SET (libsolv_HEADERS - bitmap.h evr.h hash.h policy.h poolarch.h poolvendor.h pool.h -diff --git a/src/diskusage.c b/src/diskusage.c -new file mode 100644 -index 0000000..b764b98 ---- /dev/null -+++ b/src/diskusage.c -@@ -0,0 +1,348 @@ -+/* -+ * Copyright (c) 2007-2016, SUSE LLC -+ * -+ * This program is licensed under the BSD license, read LICENSE.BSD -+ * for further information -+ */ -+ -+/* -+ * diskusage.c -+ * -+ * calculate needed space on partitions -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "pool.h" -+#include "poolarch.h" -+#include "repo.h" -+#include "util.h" -+#include "bitmap.h" -+ -+ -+struct mptree { -+ Id sibling; -+ Id child; -+ const char *comp; -+ int compl; -+ Id mountpoint; -+}; -+ -+struct ducbdata { -+ DUChanges *mps; -+ struct mptree *mptree; -+ int addsub; -+ int hasdu; -+ -+ Id *dirmap; -+ int nmap; -+ Repodata *olddata; -+}; -+ -+ -+static int -+solver_fill_DU_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *value) -+{ -+ struct ducbdata *cbd = cbdata; -+ Id mp; -+ -+ if (data != cbd->olddata) -+ { -+ Id dn, mp, comp, *dirmap, *dirs; -+ int i, compl; -+ const char *compstr; -+ struct mptree *mptree; -+ -+ /* create map from dir to mptree */ -+ cbd->dirmap = solv_free(cbd->dirmap); -+ cbd->nmap = 0; -+ dirmap = solv_calloc(data->dirpool.ndirs, sizeof(Id)); -+ mptree = cbd->mptree; -+ mp = 0; -+ for (dn = 2, dirs = data->dirpool.dirs + dn; dn < data->dirpool.ndirs; dn++) -+ { -+ comp = *dirs++; -+ if (comp <= 0) -+ { -+ mp = dirmap[-comp]; -+ continue; -+ } -+ if (mp < 0) -+ { -+ /* unconnected */ -+ dirmap[dn] = mp; -+ continue; -+ } -+ if (!mptree[mp].child) -+ { -+ dirmap[dn] = -mp; -+ continue; -+ } -+ if (data->localpool) -+ compstr = stringpool_id2str(&data->spool, comp); -+ else -+ compstr = pool_id2str(data->repo->pool, comp); -+ compl = strlen(compstr); -+ for (i = mptree[mp].child; i; i = mptree[i].sibling) -+ if (mptree[i].compl == compl && !strncmp(mptree[i].comp, compstr, compl)) -+ break; -+ dirmap[dn] = i ? i : -mp; -+ } -+ /* change dirmap to point to mountpoint instead of mptree */ -+ for (dn = 0; dn < data->dirpool.ndirs; dn++) -+ { -+ mp = dirmap[dn]; -+ dirmap[dn] = mptree[mp > 0 ? mp : -mp].mountpoint; -+ } -+ cbd->dirmap = dirmap; -+ cbd->nmap = data->dirpool.ndirs; -+ cbd->olddata = data; -+ } -+ cbd->hasdu = 1; -+ if (value->id < 0 || value->id >= cbd->nmap) -+ return 0; -+ mp = cbd->dirmap[value->id]; -+ if (mp < 0) -+ return 0; -+ if (cbd->addsub > 0) -+ { -+ cbd->mps[mp].kbytes += value->num; -+ cbd->mps[mp].files += value->num2; -+ } -+ else if (!(cbd->mps[mp].flags & DUCHANGES_ONLYADD)) -+ { -+ cbd->mps[mp].kbytes -= value->num; -+ cbd->mps[mp].files -= value->num2; -+ } -+ return 0; -+} -+ -+static void -+propagate_mountpoints(struct mptree *mptree, int pos, Id mountpoint) -+{ -+ int i; -+ if (mptree[pos].mountpoint == -1) -+ mptree[pos].mountpoint = mountpoint; -+ else -+ mountpoint = mptree[pos].mountpoint; -+ for (i = mptree[pos].child; i; i = mptree[i].sibling) -+ propagate_mountpoints(mptree, i, mountpoint); -+} -+ -+#define MPTREE_BLOCK 15 -+ -+static struct mptree * -+create_mptree(DUChanges *mps, int nmps) -+{ -+ int i, nmptree; -+ struct mptree *mptree; -+ int pos, compl; -+ int mp; -+ const char *p, *path, *compstr; -+ -+ mptree = solv_extend_resize(0, 1, sizeof(struct mptree), MPTREE_BLOCK); -+ -+ /* our root node */ -+ mptree[0].sibling = 0; -+ mptree[0].child = 0; -+ mptree[0].comp = 0; -+ mptree[0].compl = 0; -+ mptree[0].mountpoint = -1; -+ nmptree = 1; -+ -+ /* create component tree */ -+ for (mp = 0; mp < nmps; mp++) -+ { -+ mps[mp].kbytes = 0; -+ mps[mp].files = 0; -+ pos = 0; -+ path = mps[mp].path; -+ while(*path == '/') -+ path++; -+ while (*path) -+ { -+ if ((p = strchr(path, '/')) == 0) -+ { -+ compstr = path; -+ compl = strlen(compstr); -+ path += compl; -+ } -+ else -+ { -+ compstr = path; -+ compl = p - path; -+ path = p + 1; -+ while(*path == '/') -+ path++; -+ } -+ for (i = mptree[pos].child; i; i = mptree[i].sibling) -+ if (mptree[i].compl == compl && !strncmp(mptree[i].comp, compstr, compl)) -+ break; -+ if (!i) -+ { -+ /* create new node */ -+ mptree = solv_extend(mptree, nmptree, 1, sizeof(struct mptree), MPTREE_BLOCK); -+ i = nmptree++; -+ mptree[i].sibling = mptree[pos].child; -+ mptree[i].child = 0; -+ mptree[i].comp = compstr; -+ mptree[i].compl = compl; -+ mptree[i].mountpoint = -1; -+ mptree[pos].child = i; -+ } -+ pos = i; -+ } -+ mptree[pos].mountpoint = mp; -+ } -+ -+ propagate_mountpoints(mptree, 0, mptree[0].mountpoint); -+ -+#if 0 -+ for (i = 0; i < nmptree; i++) -+ { -+ printf("#%d sibling: %d\n", i, mptree[i].sibling); -+ printf("#%d child: %d\n", i, mptree[i].child); -+ printf("#%d comp: %s\n", i, mptree[i].comp); -+ printf("#%d compl: %d\n", i, mptree[i].compl); -+ printf("#%d mountpont: %d\n", i, mptree[i].mountpoint); -+ } -+#endif -+ -+ return mptree; -+} -+ -+void -+pool_calc_duchanges(Pool *pool, Map *installedmap, DUChanges *mps, int nmps) -+{ -+ struct mptree *mptree; -+ struct ducbdata cbd; -+ Solvable *s; -+ int i, sp; -+ Map ignoredu; -+ Repo *oldinstalled = pool->installed; -+ int haveonlyadd = 0; -+ -+ map_init(&ignoredu, 0); -+ mptree = create_mptree(mps, nmps); -+ -+ for (i = 0; i < nmps; i++) -+ if ((mps[i].flags & DUCHANGES_ONLYADD) != 0) -+ haveonlyadd = 1; -+ cbd.mps = mps; -+ cbd.dirmap = 0; -+ cbd.nmap = 0; -+ cbd.olddata = 0; -+ cbd.mptree = mptree; -+ cbd.addsub = 1; -+ for (sp = 1, s = pool->solvables + sp; sp < pool->nsolvables; sp++, s++) -+ { -+ if (!s->repo || (oldinstalled && s->repo == oldinstalled)) -+ continue; -+ if (!MAPTST(installedmap, sp)) -+ continue; -+ cbd.hasdu = 0; -+ repo_search(s->repo, sp, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); -+ if (!cbd.hasdu && oldinstalled) -+ { -+ Id op, opp; -+ int didonlyadd = 0; -+ /* no du data available, ignore data of all installed solvables we obsolete */ -+ if (!ignoredu.size) -+ map_grow(&ignoredu, oldinstalled->end - oldinstalled->start); -+ FOR_PROVIDES(op, opp, s->name) -+ { -+ Solvable *s2 = pool->solvables + op; -+ if (!pool->implicitobsoleteusesprovides && s->name != s2->name) -+ continue; -+ if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, s2)) -+ continue; -+ if (op >= oldinstalled->start && op < oldinstalled->end) -+ { -+ MAPSET(&ignoredu, op - oldinstalled->start); -+ if (haveonlyadd && pool->solvables[op].repo == oldinstalled && !didonlyadd) -+ { -+ repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); -+ cbd.addsub = -1; -+ repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); -+ cbd.addsub = 1; -+ didonlyadd = 1; -+ } -+ } -+ } -+ if (s->obsoletes) -+ { -+ Id obs, *obsp = s->repo->idarraydata + s->obsoletes; -+ while ((obs = *obsp++) != 0) -+ FOR_PROVIDES(op, opp, obs) -+ { -+ Solvable *s2 = pool->solvables + op; -+ if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, s2, obs)) -+ continue; -+ if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2)) -+ continue; -+ if (op >= oldinstalled->start && op < oldinstalled->end) -+ { -+ MAPSET(&ignoredu, op - oldinstalled->start); -+ if (haveonlyadd && pool->solvables[op].repo == oldinstalled && !didonlyadd) -+ { -+ repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); -+ cbd.addsub = -1; -+ repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); -+ cbd.addsub = 1; -+ didonlyadd = 1; -+ } -+ } -+ } -+ } -+ } -+ } -+ cbd.addsub = -1; -+ if (oldinstalled) -+ { -+ /* assumes we allways have du data for installed solvables */ -+ FOR_REPO_SOLVABLES(oldinstalled, sp, s) -+ { -+ if (MAPTST(installedmap, sp)) -+ continue; -+ if (ignoredu.map && MAPTST(&ignoredu, sp - oldinstalled->start)) -+ continue; -+ repo_search(oldinstalled, sp, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); -+ } -+ } -+ map_free(&ignoredu); -+ solv_free(cbd.dirmap); -+ solv_free(mptree); -+} -+ -+int -+pool_calc_installsizechange(Pool *pool, Map *installedmap) -+{ -+ Id sp; -+ Solvable *s; -+ int change = 0; -+ Repo *oldinstalled = pool->installed; -+ -+ for (sp = 1, s = pool->solvables + sp; sp < pool->nsolvables; sp++, s++) -+ { -+ if (!s->repo || (oldinstalled && s->repo == oldinstalled)) -+ continue; -+ if (!MAPTST(installedmap, sp)) -+ continue; -+ change += solvable_lookup_sizek(s, SOLVABLE_INSTALLSIZE, 0); -+ } -+ if (oldinstalled) -+ { -+ FOR_REPO_SOLVABLES(oldinstalled, sp, s) -+ { -+ if (MAPTST(installedmap, sp)) -+ continue; -+ change -= solvable_lookup_sizek(s, SOLVABLE_INSTALLSIZE, 0); -+ } -+ } -+ return change; -+} -+ -diff --git a/src/fileprovides.c b/src/fileprovides.c -new file mode 100644 -index 0000000..11ff4f5 ---- /dev/null -+++ b/src/fileprovides.c -@@ -0,0 +1,373 @@ -+/* -+ * Copyright (c) 2007-2016, SUSE LLC -+ * -+ * This program is licensed under the BSD license, read LICENSE.BSD -+ * for further information -+ */ -+ -+/* -+ * fileprovides.c -+ * -+ * Add missing file dependencies to the package provides -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "pool.h" -+#include "repo.h" -+#include "util.h" -+#include "bitmap.h" -+ -+struct searchfiles { -+ Id *ids; -+ int nfiles; -+ Map seen; -+}; -+ -+#define SEARCHFILES_BLOCK 127 -+ -+static void -+pool_addfileprovides_dep(Pool *pool, Id *ida, struct searchfiles *sf, struct searchfiles *isf) -+{ -+ Id dep, sid; -+ const char *s; -+ struct searchfiles *csf; -+ -+ while ((dep = *ida++) != 0) -+ { -+ csf = sf; -+ while (ISRELDEP(dep)) -+ { -+ Reldep *rd; -+ sid = pool->ss.nstrings + GETRELID(dep); -+ if (MAPTST(&csf->seen, sid)) -+ { -+ dep = 0; -+ break; -+ } -+ MAPSET(&csf->seen, sid); -+ rd = GETRELDEP(pool, dep); -+ if (rd->flags < 8) -+ dep = rd->name; -+ else if (rd->flags == REL_NAMESPACE) -+ { -+ if (rd->name == NAMESPACE_SPLITPROVIDES) -+ { -+ csf = isf; -+ if (!csf || MAPTST(&csf->seen, sid)) -+ { -+ dep = 0; -+ break; -+ } -+ MAPSET(&csf->seen, sid); -+ } -+ dep = rd->evr; -+ } -+ else if (rd->flags == REL_FILECONFLICT) -+ { -+ dep = 0; -+ break; -+ } -+ else -+ { -+ Id ids[2]; -+ ids[0] = rd->name; -+ ids[1] = 0; -+ pool_addfileprovides_dep(pool, ids, csf, isf); -+ dep = rd->evr; -+ } -+ } -+ if (!dep) -+ continue; -+ if (MAPTST(&csf->seen, dep)) -+ continue; -+ MAPSET(&csf->seen, dep); -+ s = pool_id2str(pool, dep); -+ if (*s != '/') -+ continue; -+ if (csf != isf && pool->addedfileprovides == 1 && !repodata_filelistfilter_matches(0, s)) -+ continue; /* skip non-standard locations csf == isf: installed case */ -+ csf->ids = solv_extend(csf->ids, csf->nfiles, 1, sizeof(Id), SEARCHFILES_BLOCK); -+ csf->ids[csf->nfiles++] = dep; -+ } -+} -+ -+struct addfileprovides_cbdata { -+ int nfiles; -+ Id *ids; -+ char **dirs; -+ char **names; -+ -+ Id *dids; -+ -+ Map providedids; -+ -+ Map useddirs; -+}; -+ -+static int -+addfileprovides_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *value) -+{ -+ struct addfileprovides_cbdata *cbd = cbdata; -+ int i; -+ -+ if (!cbd->useddirs.size) -+ { -+ map_init(&cbd->useddirs, data->dirpool.ndirs + 1); -+ if (!cbd->dirs) -+ { -+ cbd->dirs = solv_malloc2(cbd->nfiles, sizeof(char *)); -+ cbd->names = solv_malloc2(cbd->nfiles, sizeof(char *)); -+ for (i = 0; i < cbd->nfiles; i++) -+ { -+ char *s = solv_strdup(pool_id2str(data->repo->pool, cbd->ids[i])); -+ cbd->dirs[i] = s; -+ s = strrchr(s, '/'); -+ *s = 0; -+ cbd->names[i] = s + 1; -+ } -+ } -+ for (i = 0; i < cbd->nfiles; i++) -+ { -+ Id did; -+ if (MAPTST(&cbd->providedids, cbd->ids[i])) -+ { -+ cbd->dids[i] = 0; -+ continue; -+ } -+ did = repodata_str2dir(data, cbd->dirs[i], 0); -+ cbd->dids[i] = did; -+ if (did) -+ MAPSET(&cbd->useddirs, did); -+ } -+ repodata_free_dircache(data); -+ } -+ if (value->id >= data->dirpool.ndirs || !MAPTST(&cbd->useddirs, value->id)) -+ return 0; -+ for (i = 0; i < cbd->nfiles; i++) -+ if (cbd->dids[i] == value->id && !strcmp(cbd->names[i], value->str)) -+ s->provides = repo_addid_dep(s->repo, s->provides, cbd->ids[i], SOLVABLE_FILEMARKER); -+ return 0; -+} -+ -+static void -+pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, struct searchfiles *sf, Repo *repoonly) -+{ -+ Id p; -+ Repodata *data; -+ Repo *repo; -+ Queue fileprovidesq; -+ int i, j, repoid, repodataid; -+ int provstart, provend; -+ Map donemap; -+ int ndone, incomplete; -+ -+ if (!pool->urepos) -+ return; -+ -+ cbd->nfiles = sf->nfiles; -+ cbd->ids = sf->ids; -+ cbd->dirs = 0; -+ cbd->names = 0; -+ cbd->dids = solv_realloc2(cbd->dids, sf->nfiles, sizeof(Id)); -+ map_init(&cbd->providedids, pool->ss.nstrings); -+ -+ repoid = 1; -+ repo = repoonly ? repoonly : pool->repos[repoid]; -+ map_init(&donemap, pool->nsolvables); -+ queue_init(&fileprovidesq); -+ provstart = provend = 0; -+ for (;;) -+ { -+ if (!repo || repo->disabled) -+ { -+ if (repoonly || ++repoid == pool->nrepos) -+ break; -+ repo = pool->repos[repoid]; -+ continue; -+ } -+ ndone = 0; -+ FOR_REPODATAS(repo, repodataid, data) -+ { -+ if (ndone >= repo->nsolvables) -+ break; -+ -+ if (repodata_lookup_idarray(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &fileprovidesq)) -+ { -+ map_empty(&cbd->providedids); -+ for (i = 0; i < fileprovidesq.count; i++) -+ MAPSET(&cbd->providedids, fileprovidesq.elements[i]); -+ provstart = data->start; -+ provend = data->end; -+ for (i = 0; i < cbd->nfiles; i++) -+ if (!MAPTST(&cbd->providedids, cbd->ids[i])) -+ break; -+ if (i == cbd->nfiles) -+ { -+ /* great! no need to search files */ -+ for (p = data->start; p < data->end; p++) -+ if (pool->solvables[p].repo == repo) -+ { -+ if (MAPTST(&donemap, p)) -+ continue; -+ MAPSET(&donemap, p); -+ ndone++; -+ } -+ continue; -+ } -+ } -+ -+ if (!repodata_has_keyname(data, SOLVABLE_FILELIST)) -+ continue; -+ -+ if (data->start < provstart || data->end > provend) -+ { -+ map_empty(&cbd->providedids); -+ provstart = provend = 0; -+ } -+ -+ /* check if the data is incomplete */ -+ incomplete = 0; -+ if (data->state == REPODATA_AVAILABLE) -+ { -+ for (j = 1; j < data->nkeys; j++) -+ if (data->keys[j].name != REPOSITORY_SOLVABLES && data->keys[j].name != SOLVABLE_FILELIST) -+ break; -+ if (j < data->nkeys) -+ { -+#if 0 -+ for (i = 0; i < cbd->nfiles; i++) -+ if (!MAPTST(&cbd->providedids, cbd->ids[i]) && !repodata_filelistfilter_matches(data, pool_id2str(pool, cbd->ids[i]))) -+ printf("need complete filelist because of %s\n", pool_id2str(pool, cbd->ids[i])); -+#endif -+ for (i = 0; i < cbd->nfiles; i++) -+ if (!MAPTST(&cbd->providedids, cbd->ids[i]) && !repodata_filelistfilter_matches(data, pool_id2str(pool, cbd->ids[i]))) -+ break; -+ if (i < cbd->nfiles) -+ incomplete = 1; -+ } -+ } -+ -+ /* do the search */ -+ map_init(&cbd->useddirs, 0); -+ for (p = data->start; p < data->end; p++) -+ if (pool->solvables[p].repo == repo) -+ { -+ if (MAPTST(&donemap, p)) -+ continue; -+ repodata_search(data, p, SOLVABLE_FILELIST, 0, addfileprovides_cb, cbd); -+ if (!incomplete) -+ { -+ MAPSET(&donemap, p); -+ ndone++; -+ } -+ } -+ map_free(&cbd->useddirs); -+ } -+ -+ if (repoonly || ++repoid == pool->nrepos) -+ break; -+ repo = pool->repos[repoid]; -+ } -+ map_free(&donemap); -+ queue_free(&fileprovidesq); -+ map_free(&cbd->providedids); -+ if (cbd->dirs) -+ { -+ for (i = 0; i < cbd->nfiles; i++) -+ solv_free(cbd->dirs[i]); -+ cbd->dirs = solv_free(cbd->dirs); -+ cbd->names = solv_free(cbd->names); -+ } -+} -+ -+void -+pool_addfileprovides_queue(Pool *pool, Queue *idq, Queue *idqinst) -+{ -+ Solvable *s; -+ Repo *installed, *repo; -+ struct searchfiles sf, isf, *isfp; -+ struct addfileprovides_cbdata cbd; -+ int i; -+ unsigned int now; -+ -+ installed = pool->installed; -+ now = solv_timems(0); -+ memset(&sf, 0, sizeof(sf)); -+ map_init(&sf.seen, pool->ss.nstrings + pool->nrels); -+ memset(&isf, 0, sizeof(isf)); -+ map_init(&isf.seen, pool->ss.nstrings + pool->nrels); -+ pool->addedfileprovides = pool->addfileprovidesfiltered ? 1 : 2; -+ -+ 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++) -+ { -+ repo = s->repo; -+ if (!repo) -+ continue; -+ if (s->obsoletes) -+ pool_addfileprovides_dep(pool, repo->idarraydata + s->obsoletes, &sf, isfp); -+ if (s->conflicts) -+ pool_addfileprovides_dep(pool, repo->idarraydata + s->conflicts, &sf, isfp); -+ if (s->requires) -+ pool_addfileprovides_dep(pool, repo->idarraydata + s->requires, &sf, isfp); -+ if (s->recommends) -+ pool_addfileprovides_dep(pool, repo->idarraydata + s->recommends, &sf, isfp); -+ if (s->suggests) -+ pool_addfileprovides_dep(pool, repo->idarraydata + s->suggests, &sf, isfp); -+ if (s->supplements) -+ pool_addfileprovides_dep(pool, repo->idarraydata + s->supplements, &sf, isfp); -+ if (s->enhances) -+ pool_addfileprovides_dep(pool, repo->idarraydata + s->enhances, &sf, isfp); -+ } -+ map_free(&sf.seen); -+ map_free(&isf.seen); -+ POOL_DEBUG(SOLV_DEBUG_STATS, "found %d file dependencies, %d installed file dependencies\n", sf.nfiles, isf.nfiles); -+ cbd.dids = 0; -+ if (sf.nfiles) -+ { -+#if 0 -+ for (i = 0; i < sf.nfiles; i++) -+ POOL_DEBUG(SOLV_DEBUG_STATS, "looking up %s in filelist\n", pool_id2str(pool, sf.ids[i])); -+#endif -+ pool_addfileprovides_search(pool, &cbd, &sf, 0); -+ 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); -+ } -+ if (isf.nfiles) -+ { -+#if 0 -+ for (i = 0; i < isf.nfiles; i++) -+ POOL_DEBUG(SOLV_DEBUG_STATS, "looking up %s in installed filelist\n", pool_id2str(pool, isf.ids[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); -+ } -+ solv_free(cbd.dids); -+ pool_freewhatprovides(pool); /* as we have added provides */ -+ POOL_DEBUG(SOLV_DEBUG_STATS, "addfileprovides took %d ms\n", solv_timems(now)); -+} -+ -+void -+pool_addfileprovides(Pool *pool) -+{ -+ pool_addfileprovides_queue(pool, 0, 0); -+} -+ -diff --git a/src/pool.c b/src/pool.c -index 85932bf..34fd787 100644 ---- a/src/pool.c -+++ b/src/pool.c -@@ -1412,357 +1412,6 @@ void pool_setnamespacecallback(Pool *pool, Id (*cb)(struct _Pool *, void *, Id, - pool->nscallbackdata = nscbdata; - } - --/*************************************************************************/ -- --struct searchfiles { -- Id *ids; -- int nfiles; -- Map seen; --}; -- --#define SEARCHFILES_BLOCK 127 -- --static void --pool_addfileprovides_dep(Pool *pool, Id *ida, struct searchfiles *sf, struct searchfiles *isf) --{ -- Id dep, sid; -- const char *s; -- struct searchfiles *csf; -- -- while ((dep = *ida++) != 0) -- { -- csf = sf; -- while (ISRELDEP(dep)) -- { -- Reldep *rd; -- sid = pool->ss.nstrings + GETRELID(dep); -- if (MAPTST(&csf->seen, sid)) -- { -- dep = 0; -- break; -- } -- MAPSET(&csf->seen, sid); -- rd = GETRELDEP(pool, dep); -- if (rd->flags < 8) -- dep = rd->name; -- else if (rd->flags == REL_NAMESPACE) -- { -- if (rd->name == NAMESPACE_SPLITPROVIDES) -- { -- csf = isf; -- if (!csf || MAPTST(&csf->seen, sid)) -- { -- dep = 0; -- break; -- } -- MAPSET(&csf->seen, sid); -- } -- dep = rd->evr; -- } -- else if (rd->flags == REL_FILECONFLICT) -- { -- dep = 0; -- break; -- } -- else -- { -- Id ids[2]; -- ids[0] = rd->name; -- ids[1] = 0; -- pool_addfileprovides_dep(pool, ids, csf, isf); -- dep = rd->evr; -- } -- } -- if (!dep) -- continue; -- if (MAPTST(&csf->seen, dep)) -- continue; -- MAPSET(&csf->seen, dep); -- s = pool_id2str(pool, dep); -- if (*s != '/') -- continue; -- if (csf != isf && pool->addedfileprovides == 1 && !repodata_filelistfilter_matches(0, s)) -- continue; /* skip non-standard locations csf == isf: installed case */ -- csf->ids = solv_extend(csf->ids, csf->nfiles, 1, sizeof(Id), SEARCHFILES_BLOCK); -- csf->ids[csf->nfiles++] = dep; -- } --} -- --struct addfileprovides_cbdata { -- int nfiles; -- Id *ids; -- char **dirs; -- char **names; -- -- Id *dids; -- -- Map providedids; -- -- Map useddirs; --}; -- --static int --addfileprovides_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *value) --{ -- struct addfileprovides_cbdata *cbd = cbdata; -- int i; -- -- if (!cbd->useddirs.size) -- { -- map_init(&cbd->useddirs, data->dirpool.ndirs + 1); -- if (!cbd->dirs) -- { -- cbd->dirs = solv_malloc2(cbd->nfiles, sizeof(char *)); -- cbd->names = solv_malloc2(cbd->nfiles, sizeof(char *)); -- for (i = 0; i < cbd->nfiles; i++) -- { -- char *s = solv_strdup(pool_id2str(data->repo->pool, cbd->ids[i])); -- cbd->dirs[i] = s; -- s = strrchr(s, '/'); -- *s = 0; -- cbd->names[i] = s + 1; -- } -- } -- for (i = 0; i < cbd->nfiles; i++) -- { -- Id did; -- if (MAPTST(&cbd->providedids, cbd->ids[i])) -- { -- cbd->dids[i] = 0; -- continue; -- } -- did = repodata_str2dir(data, cbd->dirs[i], 0); -- cbd->dids[i] = did; -- if (did) -- MAPSET(&cbd->useddirs, did); -- } -- repodata_free_dircache(data); -- } -- if (value->id >= data->dirpool.ndirs || !MAPTST(&cbd->useddirs, value->id)) -- return 0; -- for (i = 0; i < cbd->nfiles; i++) -- if (cbd->dids[i] == value->id && !strcmp(cbd->names[i], value->str)) -- s->provides = repo_addid_dep(s->repo, s->provides, cbd->ids[i], SOLVABLE_FILEMARKER); -- return 0; --} -- --static void --pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, struct searchfiles *sf, Repo *repoonly) --{ -- Id p; -- Repodata *data; -- Repo *repo; -- Queue fileprovidesq; -- int i, j, repoid, repodataid; -- int provstart, provend; -- Map donemap; -- int ndone, incomplete; -- -- if (!pool->urepos) -- return; -- -- cbd->nfiles = sf->nfiles; -- cbd->ids = sf->ids; -- cbd->dirs = 0; -- cbd->names = 0; -- cbd->dids = solv_realloc2(cbd->dids, sf->nfiles, sizeof(Id)); -- map_init(&cbd->providedids, pool->ss.nstrings); -- -- repoid = 1; -- repo = repoonly ? repoonly : pool->repos[repoid]; -- map_init(&donemap, pool->nsolvables); -- queue_init(&fileprovidesq); -- provstart = provend = 0; -- for (;;) -- { -- if (!repo || repo->disabled) -- { -- if (repoonly || ++repoid == pool->nrepos) -- break; -- repo = pool->repos[repoid]; -- continue; -- } -- ndone = 0; -- FOR_REPODATAS(repo, repodataid, data) -- { -- if (ndone >= repo->nsolvables) -- break; -- -- if (repodata_lookup_idarray(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &fileprovidesq)) -- { -- map_empty(&cbd->providedids); -- for (i = 0; i < fileprovidesq.count; i++) -- MAPSET(&cbd->providedids, fileprovidesq.elements[i]); -- provstart = data->start; -- provend = data->end; -- for (i = 0; i < cbd->nfiles; i++) -- if (!MAPTST(&cbd->providedids, cbd->ids[i])) -- break; -- if (i == cbd->nfiles) -- { -- /* great! no need to search files */ -- for (p = data->start; p < data->end; p++) -- if (pool->solvables[p].repo == repo) -- { -- if (MAPTST(&donemap, p)) -- continue; -- MAPSET(&donemap, p); -- ndone++; -- } -- continue; -- } -- } -- -- if (!repodata_has_keyname(data, SOLVABLE_FILELIST)) -- continue; -- -- if (data->start < provstart || data->end > provend) -- { -- map_empty(&cbd->providedids); -- provstart = provend = 0; -- } -- -- /* check if the data is incomplete */ -- incomplete = 0; -- if (data->state == REPODATA_AVAILABLE) -- { -- for (j = 1; j < data->nkeys; j++) -- if (data->keys[j].name != REPOSITORY_SOLVABLES && data->keys[j].name != SOLVABLE_FILELIST) -- break; -- if (j < data->nkeys) -- { --#if 0 -- for (i = 0; i < cbd->nfiles; i++) -- if (!MAPTST(&cbd->providedids, cbd->ids[i]) && !repodata_filelistfilter_matches(data, pool_id2str(pool, cbd->ids[i]))) -- printf("need complete filelist because of %s\n", pool_id2str(pool, cbd->ids[i])); --#endif -- for (i = 0; i < cbd->nfiles; i++) -- if (!MAPTST(&cbd->providedids, cbd->ids[i]) && !repodata_filelistfilter_matches(data, pool_id2str(pool, cbd->ids[i]))) -- break; -- if (i < cbd->nfiles) -- incomplete = 1; -- } -- } -- -- /* do the search */ -- map_init(&cbd->useddirs, 0); -- for (p = data->start; p < data->end; p++) -- if (pool->solvables[p].repo == repo) -- { -- if (MAPTST(&donemap, p)) -- continue; -- repodata_search(data, p, SOLVABLE_FILELIST, 0, addfileprovides_cb, cbd); -- if (!incomplete) -- { -- MAPSET(&donemap, p); -- ndone++; -- } -- } -- map_free(&cbd->useddirs); -- } -- -- if (repoonly || ++repoid == pool->nrepos) -- break; -- repo = pool->repos[repoid]; -- } -- map_free(&donemap); -- queue_free(&fileprovidesq); -- map_free(&cbd->providedids); -- if (cbd->dirs) -- { -- for (i = 0; i < cbd->nfiles; i++) -- solv_free(cbd->dirs[i]); -- cbd->dirs = solv_free(cbd->dirs); -- cbd->names = solv_free(cbd->names); -- } --} -- --void --pool_addfileprovides_queue(Pool *pool, Queue *idq, Queue *idqinst) --{ -- Solvable *s; -- Repo *installed, *repo; -- struct searchfiles sf, isf, *isfp; -- struct addfileprovides_cbdata cbd; -- int i; -- unsigned int now; -- -- installed = pool->installed; -- now = solv_timems(0); -- memset(&sf, 0, sizeof(sf)); -- map_init(&sf.seen, pool->ss.nstrings + pool->nrels); -- memset(&isf, 0, sizeof(isf)); -- map_init(&isf.seen, pool->ss.nstrings + pool->nrels); -- pool->addedfileprovides = pool->addfileprovidesfiltered ? 1 : 2; -- -- 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++) -- { -- repo = s->repo; -- if (!repo) -- continue; -- if (s->obsoletes) -- pool_addfileprovides_dep(pool, repo->idarraydata + s->obsoletes, &sf, isfp); -- if (s->conflicts) -- pool_addfileprovides_dep(pool, repo->idarraydata + s->conflicts, &sf, isfp); -- if (s->requires) -- pool_addfileprovides_dep(pool, repo->idarraydata + s->requires, &sf, isfp); -- if (s->recommends) -- pool_addfileprovides_dep(pool, repo->idarraydata + s->recommends, &sf, isfp); -- if (s->suggests) -- pool_addfileprovides_dep(pool, repo->idarraydata + s->suggests, &sf, isfp); -- if (s->supplements) -- pool_addfileprovides_dep(pool, repo->idarraydata + s->supplements, &sf, isfp); -- if (s->enhances) -- pool_addfileprovides_dep(pool, repo->idarraydata + s->enhances, &sf, isfp); -- } -- map_free(&sf.seen); -- map_free(&isf.seen); -- POOL_DEBUG(SOLV_DEBUG_STATS, "found %d file dependencies, %d installed file dependencies\n", sf.nfiles, isf.nfiles); -- cbd.dids = 0; -- if (sf.nfiles) -- { --#if 0 -- for (i = 0; i < sf.nfiles; i++) -- POOL_DEBUG(SOLV_DEBUG_STATS, "looking up %s in filelist\n", pool_id2str(pool, sf.ids[i])); --#endif -- pool_addfileprovides_search(pool, &cbd, &sf, 0); -- 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); -- } -- if (isf.nfiles) -- { --#if 0 -- for (i = 0; i < isf.nfiles; i++) -- POOL_DEBUG(SOLV_DEBUG_STATS, "looking up %s in installed filelist\n", pool_id2str(pool, isf.ids[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); -- } -- solv_free(cbd.dids); -- pool_freewhatprovides(pool); /* as we have added provides */ -- POOL_DEBUG(SOLV_DEBUG_STATS, "addfileprovides took %d ms\n", solv_timems(now)); --} -- --void --pool_addfileprovides(Pool *pool) --{ -- pool_addfileprovides_queue(pool, 0, 0); --} -- - void - pool_search(Pool *pool, Id p, Id key, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, struct _Repodata *data, struct _Repokey *key, struct _KeyValue *kv), void *cbdata) - { -@@ -1784,7 +1433,6 @@ pool_clear_pos(Pool *pool) - memset(&pool->pos, 0, sizeof(pool->pos)); - } - -- - void - pool_set_languages(Pool *pool, const char **languages, int nlanguages) - { -@@ -1951,330 +1599,6 @@ pool_bin2hex(Pool *pool, const unsigned char *buf, int len) - return s; - } - --/*******************************************************************/ -- --struct mptree { -- Id sibling; -- Id child; -- const char *comp; -- int compl; -- Id mountpoint; --}; -- --struct ducbdata { -- DUChanges *mps; -- struct mptree *mptree; -- int addsub; -- int hasdu; -- -- Id *dirmap; -- int nmap; -- Repodata *olddata; --}; -- -- --static int --solver_fill_DU_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *value) --{ -- struct ducbdata *cbd = cbdata; -- Id mp; -- -- if (data != cbd->olddata) -- { -- Id dn, mp, comp, *dirmap, *dirs; -- int i, compl; -- const char *compstr; -- struct mptree *mptree; -- -- /* create map from dir to mptree */ -- cbd->dirmap = solv_free(cbd->dirmap); -- cbd->nmap = 0; -- dirmap = solv_calloc(data->dirpool.ndirs, sizeof(Id)); -- mptree = cbd->mptree; -- mp = 0; -- for (dn = 2, dirs = data->dirpool.dirs + dn; dn < data->dirpool.ndirs; dn++) -- { -- comp = *dirs++; -- if (comp <= 0) -- { -- mp = dirmap[-comp]; -- continue; -- } -- if (mp < 0) -- { -- /* unconnected */ -- dirmap[dn] = mp; -- continue; -- } -- if (!mptree[mp].child) -- { -- dirmap[dn] = -mp; -- continue; -- } -- if (data->localpool) -- compstr = stringpool_id2str(&data->spool, comp); -- else -- compstr = pool_id2str(data->repo->pool, comp); -- compl = strlen(compstr); -- for (i = mptree[mp].child; i; i = mptree[i].sibling) -- if (mptree[i].compl == compl && !strncmp(mptree[i].comp, compstr, compl)) -- break; -- dirmap[dn] = i ? i : -mp; -- } -- /* change dirmap to point to mountpoint instead of mptree */ -- for (dn = 0; dn < data->dirpool.ndirs; dn++) -- { -- mp = dirmap[dn]; -- dirmap[dn] = mptree[mp > 0 ? mp : -mp].mountpoint; -- } -- cbd->dirmap = dirmap; -- cbd->nmap = data->dirpool.ndirs; -- cbd->olddata = data; -- } -- cbd->hasdu = 1; -- if (value->id < 0 || value->id >= cbd->nmap) -- return 0; -- mp = cbd->dirmap[value->id]; -- if (mp < 0) -- return 0; -- if (cbd->addsub > 0) -- { -- cbd->mps[mp].kbytes += value->num; -- cbd->mps[mp].files += value->num2; -- } -- else if (!(cbd->mps[mp].flags & DUCHANGES_ONLYADD)) -- { -- cbd->mps[mp].kbytes -= value->num; -- cbd->mps[mp].files -= value->num2; -- } -- return 0; --} -- --static void --propagate_mountpoints(struct mptree *mptree, int pos, Id mountpoint) --{ -- int i; -- if (mptree[pos].mountpoint == -1) -- mptree[pos].mountpoint = mountpoint; -- else -- mountpoint = mptree[pos].mountpoint; -- for (i = mptree[pos].child; i; i = mptree[i].sibling) -- propagate_mountpoints(mptree, i, mountpoint); --} -- --#define MPTREE_BLOCK 15 -- --static struct mptree * --create_mptree(DUChanges *mps, int nmps) --{ -- int i, nmptree; -- struct mptree *mptree; -- int pos, compl; -- int mp; -- const char *p, *path, *compstr; -- -- mptree = solv_extend_resize(0, 1, sizeof(struct mptree), MPTREE_BLOCK); -- -- /* our root node */ -- mptree[0].sibling = 0; -- mptree[0].child = 0; -- mptree[0].comp = 0; -- mptree[0].compl = 0; -- mptree[0].mountpoint = -1; -- nmptree = 1; -- -- /* create component tree */ -- for (mp = 0; mp < nmps; mp++) -- { -- mps[mp].kbytes = 0; -- mps[mp].files = 0; -- pos = 0; -- path = mps[mp].path; -- while(*path == '/') -- path++; -- while (*path) -- { -- if ((p = strchr(path, '/')) == 0) -- { -- compstr = path; -- compl = strlen(compstr); -- path += compl; -- } -- else -- { -- compstr = path; -- compl = p - path; -- path = p + 1; -- while(*path == '/') -- path++; -- } -- for (i = mptree[pos].child; i; i = mptree[i].sibling) -- if (mptree[i].compl == compl && !strncmp(mptree[i].comp, compstr, compl)) -- break; -- if (!i) -- { -- /* create new node */ -- mptree = solv_extend(mptree, nmptree, 1, sizeof(struct mptree), MPTREE_BLOCK); -- i = nmptree++; -- mptree[i].sibling = mptree[pos].child; -- mptree[i].child = 0; -- mptree[i].comp = compstr; -- mptree[i].compl = compl; -- mptree[i].mountpoint = -1; -- mptree[pos].child = i; -- } -- pos = i; -- } -- mptree[pos].mountpoint = mp; -- } -- -- propagate_mountpoints(mptree, 0, mptree[0].mountpoint); -- --#if 0 -- for (i = 0; i < nmptree; i++) -- { -- printf("#%d sibling: %d\n", i, mptree[i].sibling); -- printf("#%d child: %d\n", i, mptree[i].child); -- printf("#%d comp: %s\n", i, mptree[i].comp); -- printf("#%d compl: %d\n", i, mptree[i].compl); -- printf("#%d mountpont: %d\n", i, mptree[i].mountpoint); -- } --#endif -- -- return mptree; --} -- --void --pool_calc_duchanges(Pool *pool, Map *installedmap, DUChanges *mps, int nmps) --{ -- struct mptree *mptree; -- struct ducbdata cbd; -- Solvable *s; -- int i, sp; -- Map ignoredu; -- Repo *oldinstalled = pool->installed; -- int haveonlyadd = 0; -- -- map_init(&ignoredu, 0); -- mptree = create_mptree(mps, nmps); -- -- for (i = 0; i < nmps; i++) -- if ((mps[i].flags & DUCHANGES_ONLYADD) != 0) -- haveonlyadd = 1; -- cbd.mps = mps; -- cbd.dirmap = 0; -- cbd.nmap = 0; -- cbd.olddata = 0; -- cbd.mptree = mptree; -- cbd.addsub = 1; -- for (sp = 1, s = pool->solvables + sp; sp < pool->nsolvables; sp++, s++) -- { -- if (!s->repo || (oldinstalled && s->repo == oldinstalled)) -- continue; -- if (!MAPTST(installedmap, sp)) -- continue; -- cbd.hasdu = 0; -- repo_search(s->repo, sp, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); -- if (!cbd.hasdu && oldinstalled) -- { -- Id op, opp; -- int didonlyadd = 0; -- /* no du data available, ignore data of all installed solvables we obsolete */ -- if (!ignoredu.size) -- map_grow(&ignoredu, oldinstalled->end - oldinstalled->start); -- FOR_PROVIDES(op, opp, s->name) -- { -- Solvable *s2 = pool->solvables + op; -- if (!pool->implicitobsoleteusesprovides && s->name != s2->name) -- continue; -- if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, s2)) -- continue; -- if (op >= oldinstalled->start && op < oldinstalled->end) -- { -- MAPSET(&ignoredu, op - oldinstalled->start); -- if (haveonlyadd && pool->solvables[op].repo == oldinstalled && !didonlyadd) -- { -- repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); -- cbd.addsub = -1; -- repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); -- cbd.addsub = 1; -- didonlyadd = 1; -- } -- } -- } -- if (s->obsoletes) -- { -- Id obs, *obsp = s->repo->idarraydata + s->obsoletes; -- while ((obs = *obsp++) != 0) -- FOR_PROVIDES(op, opp, obs) -- { -- Solvable *s2 = pool->solvables + op; -- if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, s2, obs)) -- continue; -- if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2)) -- continue; -- if (op >= oldinstalled->start && op < oldinstalled->end) -- { -- MAPSET(&ignoredu, op - oldinstalled->start); -- if (haveonlyadd && pool->solvables[op].repo == oldinstalled && !didonlyadd) -- { -- repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); -- cbd.addsub = -1; -- repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); -- cbd.addsub = 1; -- didonlyadd = 1; -- } -- } -- } -- } -- } -- } -- cbd.addsub = -1; -- if (oldinstalled) -- { -- /* assumes we allways have du data for installed solvables */ -- FOR_REPO_SOLVABLES(oldinstalled, sp, s) -- { -- if (MAPTST(installedmap, sp)) -- continue; -- if (ignoredu.map && MAPTST(&ignoredu, sp - oldinstalled->start)) -- continue; -- repo_search(oldinstalled, sp, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); -- } -- } -- map_free(&ignoredu); -- solv_free(cbd.dirmap); -- solv_free(mptree); --} -- --int --pool_calc_installsizechange(Pool *pool, Map *installedmap) --{ -- Id sp; -- Solvable *s; -- int change = 0; -- Repo *oldinstalled = pool->installed; -- -- for (sp = 1, s = pool->solvables + sp; sp < pool->nsolvables; sp++, s++) -- { -- if (!s->repo || (oldinstalled && s->repo == oldinstalled)) -- continue; -- if (!MAPTST(installedmap, sp)) -- continue; -- change += solvable_lookup_sizek(s, SOLVABLE_INSTALLSIZE, 0); -- } -- if (oldinstalled) -- { -- FOR_REPO_SOLVABLES(oldinstalled, sp, s) -- { -- if (MAPTST(installedmap, sp)) -- continue; -- change -= solvable_lookup_sizek(s, SOLVABLE_INSTALLSIZE, 0); -- } -- } -- return change; --} -- - /* map: - * 1: installed - * 2: conflicts with installed --- -2.5.0 - diff --git a/0009-Make-_Pool_tmpspace-definition-internal.patch b/0009-Make-_Pool_tmpspace-definition-internal.patch deleted file mode 100644 index 2a40892..0000000 --- a/0009-Make-_Pool_tmpspace-definition-internal.patch +++ /dev/null @@ -1,47 +0,0 @@ -From e1f29013dd6eeb77db7fb0ad6e9343cd880ccbde Mon Sep 17 00:00:00 2001 -From: Michael Schroeder -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 - diff --git a/0010-Rework-orphan-handling-in-dup-mode.patch b/0010-Rework-orphan-handling-in-dup-mode.patch deleted file mode 100644 index d4ef098..0000000 --- a/0010-Rework-orphan-handling-in-dup-mode.patch +++ /dev/null @@ -1,311 +0,0 @@ -From 6c9cef4ef810cd32ffeee20986a16e0871fc0bae Mon Sep 17 00:00:00 2001 -From: Michael Schroeder -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 - diff --git a/libsolv.spec b/libsolv.spec index 93508bf..af211e8 100644 --- a/libsolv.spec +++ b/libsolv.spec @@ -48,23 +48,13 @@ %{nil} Name: lib%{libname} -Version: 0.6.19 -Release: 3%{?dist} +Version: 0.6.20 +Release: 1%{?dist} Summary: Package dependency solver License: BSD URL: https://github.com/openSUSE/libsolv Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz -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 BuildRequires: cmake BuildRequires: gcc-c++ @@ -312,6 +302,9 @@ popd %endif %changelog +* Sat Apr 09 2016 Igor Gnatenko - 0.6.20-1 +- Update to 0.6.20 + * Tue Apr 05 2016 Igor Gnatenko - 0.6.19-3 - Reorganize spec file - Enable helixrepo feature diff --git a/sources b/sources index 847ec0a..0d7ebaf 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -b1fe10e51190a138767aedf010525032 libsolv-0.6.19.tar.gz +9b8a44e94d048a931db8568f48e9e7f0 libsolv-0.6.20.tar.gz