From: Michael Schroeder Date: Wed, 29 Jul 2009 10:16:13 +0000 (+0200) Subject: - make addfileprovides faster X-Git-Tag: BASE-SuSE-Code-12_1-Branch~165^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=88d68a37a6fd27f2bd539bec758d56ecbbf921a2;p=thirdparty%2Flibsolv.git - make addfileprovides faster - solv: rewrite repos with complete added file provides --- diff --git a/examples/solv.c b/examples/solv.c index cc7d2043..03af6eca 100644 --- a/examples/solv.c +++ b/examples/solv.c @@ -876,6 +876,7 @@ usecachedrepo(Repo *repo, const char *repoext, unsigned char *cookie, int mark) { FILE *fp; unsigned char mycookie[32]; + unsigned char myextcookie[32]; struct repoinfo *cinfo; int flags; @@ -892,6 +893,14 @@ usecachedrepo(Repo *repo, const char *repoext, unsigned char *cookie, int mark) fclose(fp); return 0; } + if (cinfo && !repoext) + { + if (fseek(fp, -sizeof(mycookie) * 2, SEEK_END) || fread(myextcookie, sizeof(myextcookie), 1, fp) != 1) + { + fclose(fp); + return 0; + } + } rewind(fp); flags = 0; @@ -907,17 +916,8 @@ usecachedrepo(Repo *repo, const char *repoext, unsigned char *cookie, int mark) } if (cinfo && !repoext) { - /* set the checksum so that we can use it with the stub loads */ - struct stat stb; - if (!fstat(fileno(fp), &stb)) - { - int i; - - stb.st_mtime = 0; - calc_checksum_stat(&stb, REPOKEY_TYPE_SHA256, cinfo->extcookie); - for (i = 0; i < 32; i++) - cinfo->extcookie[i] ^= cinfo->cookie[i]; - } + memcpy(cinfo->cookie, mycookie, sizeof(mycookie)); + memcpy(cinfo->extcookie, myextcookie, sizeof(myextcookie)); } if (mark) futimes(fileno(fp), 0); /* try to set modification time */ @@ -928,11 +928,9 @@ usecachedrepo(Repo *repo, const char *repoext, unsigned char *cookie, int mark) void writecachedrepo(Repo *repo, Repodata *info, const char *repoext, unsigned char *cookie) { - Id *addedfileprovides = 0; FILE *fp; int i, fd; char *tmpl; - int myinfo = 0; struct repoinfo *cinfo; int onepiece; @@ -961,27 +959,46 @@ writecachedrepo(Repo *repo, Repodata *info, const char *repoext, unsigned char * if (i < repo->end) onepiece = 0; - if (!repoext) + if (!info) + repo_write(repo, fp, repo_write_stdkeyfilter, 0, 0); + else if (repoext) + repodata_write(info, fp, repo_write_stdkeyfilter, 0); + else { - if (!info) + int oldnrepodata = repo->nrepodata; + repo->nrepodata = 1; /* XXX: do this right */ + repo_write(repo, fp, repo_write_stdkeyfilter, 0, 0); + repo->nrepodata = oldnrepodata; + onepiece = 0; + } + + if (!repoext && cinfo) + { + if (!cinfo->extcookie[0]) { - info = repo_add_repodata(repo, 0); - myinfo = 1; + /* create the ext cookie and append it */ + /* we just need some unique ID */ + struct stat stb; + if (!fstat(fileno(fp), &stb)) + { + int i; + + calc_checksum_stat(&stb, REPOKEY_TYPE_SHA256, cinfo->extcookie); + for (i = 0; i < 32; i++) + cinfo->extcookie[i] ^= cookie[i]; + } + if (cinfo->extcookie[0] == 0) + cinfo->extcookie[0] = 1; } - pool_addfileprovides_ids(repo->pool, 0, &addedfileprovides); - if (addedfileprovides && *addedfileprovides) + if (fwrite(cinfo->extcookie, 32, 1, fp) != 1) { - for (i = 0; addedfileprovides[i]; i++) - repodata_add_idarray(info, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, addedfileprovides[i]); + fclose(fp); + unlink(tmpl); + free(tmpl); + return; } - sat_free(addedfileprovides); - repodata_internalize(info); - repo_write(repo, fp, repo_write_stdkeyfilter, 0, 0); } - else - repodata_write(info, fp, repo_write_stdkeyfilter, 0); - if (myinfo) - repodata_free(info); + /* append our cookie describing the metadata state */ if (fwrite(cookie, 32, 1, fp) != 1) { fclose(fp); @@ -995,20 +1012,6 @@ writecachedrepo(Repo *repo, Repodata *info, const char *repoext, unsigned char * free(tmpl); return; } - if (!repoext && cinfo) - { - /* set the checksum so that we can use it with the stub loads */ - struct stat stb; - if (!stat(tmpl, &stb)) - { - int i; - - stb.st_mtime = 0; - calc_checksum_stat(&stb, REPOKEY_TYPE_SHA256, cinfo->extcookie); - for (i = 0; i < 32; i++) - cinfo->extcookie[i] ^= cinfo->cookie[i]; - } - } if (onepiece) { /* switch to just saved repo to activate paging and save memory */ @@ -1260,7 +1263,7 @@ load_stub(Pool *pool, Repodata *data, void *dp) return 1; } #if 1 - printf(" loading]\n"); fflush(stdout); + printf(" fetching]\n"); fflush(stdout); #endif defvendor = repo_lookup_id(data->repo, SOLVID_META, SUSETAGS_DEFAULTVENDOR); descrdir = repo_lookup_str(data->repo, SOLVID_META, SUSETAGS_DESCRDIR); @@ -1293,7 +1296,7 @@ load_stub(Pool *pool, Repodata *data, void *dp) printf(" cached]\n");fflush(stdout); return 1; } - printf(" loading]\n"); fflush(stdout); + printf(" fetching]\n"); fflush(stdout); filename = repodata_lookup_str(data, SOLVID_META, REPOSITORY_REPOMD_LOCATION); filechksumtype = 0; filechksum = repodata_lookup_bin_checksum(data, SOLVID_META, REPOSITORY_REPOMD_CHECKSUM, &filechksumtype); @@ -1311,6 +1314,8 @@ load_stub(Pool *pool, Repodata *data, void *dp) return 0; } +static unsigned char installedcookie[32]; + void read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos) { @@ -1325,7 +1330,6 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos) const char *descrdir; int defvendor; struct stat stb; - unsigned char cookie[32]; Pool *sigpool = 0; Repodata *data; int badchecksum; @@ -1335,8 +1339,8 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos) printf("rpm database:"); if (stat("/var/lib/rpm/Packages", &stb)) memset(&stb, 0, sizeof(&stb)); - calc_checksum_stat(&stb, REPOKEY_TYPE_SHA256, cookie); - if (usecachedrepo(repo, 0, cookie, 0)) + calc_checksum_stat(&stb, REPOKEY_TYPE_SHA256, installedcookie); + if (usecachedrepo(repo, 0, installedcookie, 0)) printf(" cached\n"); else { @@ -1360,7 +1364,7 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos) } if (!done) repo_add_rpmdb(repo, 0, 0, REPO_REUSE_REPODATA); - writecachedrepo(repo, 0, 0, cookie); + writecachedrepo(repo, 0, 0, installedcookie); } pool_set_installed(pool, repo); @@ -1429,7 +1433,7 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos) } repo_add_repomdxml(repo, fp, 0); fclose(fp); - printf(" reading\n"); + printf(" fetching\n"); filename = repomd_find(repo, "primary", &filechksum, &filechksumtype); if (filename && (fp = curlfopen(cinfo, filename, iscompressed(filename), filechksum, filechksumtype, &badchecksum)) != 0) { @@ -1452,7 +1456,7 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos) repomd_add_ext(repo, data, "filelists"); repodata_internalize(data); if (!badchecksum) - writecachedrepo(repo, data, 0, cinfo->cookie); + writecachedrepo(repo, 0, 0, cinfo->cookie); repodata_create_stubs(repo_last_repodata(repo)); break; @@ -1512,7 +1516,7 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos) printf(" no packages file entry, skipped\n"); break; } - printf(" reading\n"); + printf(" fetching\n"); if ((fp = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), iscompressed(filename), filechksum, filechksumtype, &badchecksum)) == 0) break; /* hopeless */ repo_add_susetags(repo, fp, defvendor, 0, 0); @@ -1521,7 +1525,7 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos) susetags_add_ext(repo, data); repodata_internalize(data); if (!badchecksum) - writecachedrepo(repo, data, 0, cinfo->cookie); + writecachedrepo(repo, 0, 0, cinfo->cookie); repodata_create_stubs(repo_last_repodata(repo)); break; default: @@ -2024,6 +2028,50 @@ addsoftlocks(Pool *pool, Queue *job) #endif + +void +rewrite_repos(Pool *pool, Id *addedfileprovides) +{ + Repo *repo; + Repodata *data; + Map providedids; + Queue fileprovidesq; + Id id; + int i, j, n, nprovidedids; + struct repoinfo *cinfo; + + map_init(&providedids, pool->ss.nstrings); + queue_init(&fileprovidesq); + for (nprovidedids = 0; (id = addedfileprovides[nprovidedids]) != 0; nprovidedids++) + MAPSET(&providedids, id); + FOR_REPOS(i, repo) + { + /* make sure this repo has just one main repodata */ + if (!repo->nrepodata) + continue; + cinfo = repo->appdata; + data = repo->repodata + 0; + if (data->store.pagefd == -1) + continue; + if (repodata_lookup_idarray(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &fileprovidesq)) + { + n = 0; + for (j = 0; j < fileprovidesq.count; j++) + if (MAPTST(&providedids, fileprovidesq.elements[j])) + n++; + if (n == nprovidedids) + continue; /* nothing new added */ + } + /* oh my! */ + for (j = 0; addedfileprovides[j]; j++) + repodata_add_idarray(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, addedfileprovides[j]); + repodata_internalize(data); + writecachedrepo(repo, data, 0, cinfo ? cinfo->cookie : installedcookie); + } + queue_free(&fileprovidesq); + map_free(&providedids); +} + #define MODE_LIST 0 #define MODE_INSTALL 1 #define MODE_ERASE 2 @@ -2072,6 +2120,7 @@ main(int argc, char **argv) int allpkgs = 0; FILE **newpkgsfps; struct fcstate fcstate; + Id *addedfileprovides = 0; argc--; argv++; @@ -2215,7 +2264,11 @@ main(int argc, char **argv) // FOR_REPOS(i, repo) // printf("%s: %d solvables\n", repo->name, repo->nsolvables); - pool_addfileprovides(pool); + addedfileprovides = 0; + pool_addfileprovides_ids(pool, 0, &addedfileprovides); + if (addedfileprovides && *addedfileprovides) + rewrite_repos(pool, addedfileprovides); + sat_free(addedfileprovides); pool_createwhatprovides(pool); queue_init(&job); diff --git a/src/pool.c b/src/pool.c index ba56b581..0702f7f6 100644 --- a/src/pool.c +++ b/src/pool.c @@ -870,8 +870,10 @@ struct addfileprovides_cbdata { char **dirs; char **names; - Repodata *olddata; Id *dids; + + Map providedids; + Map useddirs; }; @@ -881,18 +883,22 @@ addfileprovides_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyV struct addfileprovides_cbdata *cbd = cbdata; int i; - if (data != cbd->olddata) + if (!cbd->useddirs.size) { - map_free(&cbd->useddirs); - map_init(&cbd->useddirs, data->dirpool.ndirs); + map_init(&cbd->useddirs, data->dirpool.ndirs + 1); for (i = 0; i < cbd->nfiles; i++) { - Id did = repodata_str2dir(data, cbd->dirs[i], 0); - cbd->dids[i] = did; + 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); } - cbd->olddata = data; } if (!MAPTST(&cbd->useddirs, value->id)) return 0; @@ -909,123 +915,128 @@ addfileprovides_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyV return 0; } -static int -addfileprovides_setid_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv) -{ - Map *provideids = cbdata; - if (key->type != REPOKEY_TYPE_IDARRAY) - return 0; - MAPSET(provideids, kv->id); - return kv->eof ? SEARCH_NEXT_SOLVABLE : 0; -} - - static void pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, struct searchfiles *sf, Repo *repoonly) { - Id p, start, end; - Solvable *s; - Repodata *data = 0, *nextdata; - Repo *repo, *oldrepo = 0; - int dataincludes = 0; - int i, j, flags; - Map providedids; - Repodata *ffldata = 0; + Id p; + Repodata *data; + Repo *repo; + Queue fileprovidesq; + int i, j, repoid, repodataid; + int provstart, provend; + Map donemap; + int ndone, incomplete; + + if (!pool->nrepos) + return; cbd->nfiles = sf->nfiles; cbd->ids = sf->ids; cbd->dirs = sf->dirs; cbd->names = sf->names; - cbd->olddata = 0; cbd->dids = sat_realloc2(cbd->dids, sf->nfiles, sizeof(Id)); - if (repoonly) - { - start = repoonly->start; - end = repoonly->end; - } - else - { - start = 2; /* skip system solvable */ - end = pool->nsolvables; - } - flags = 0; - map_init(&providedids, pool->ss.nstrings); - for (p = start, s = pool->solvables + p; p < end; p++, s++) + map_init(&cbd->providedids, pool->ss.nstrings); + + repoid = 0; + repo = repoonly ? repoonly : pool->repos[0]; + map_init(&donemap, pool->nsolvables); + queue_init(&fileprovidesq); + provstart = provend = 0; + for (;;) { - repo = s->repo; - if (!repo || (repoonly && repo != repoonly)) - continue; - /* check if p is in (oldrepo,data) */ - if (repo != oldrepo || (data && p >= data->end)) + if (repo->disabled) { - data = 0; - oldrepo = 0; + if (repoonly || ++repoid == pool->nrepos) + break; + repo = pool->repos[repoid]; + continue; } - if (oldrepo == 0) + ndone = 0; + for (data = repo->repodata, repodataid = 0; repodataid < repo->nrepodata; repodataid++, data++) { - /* nope, find new repo/repodata */ - /* if we don't find a match, set data to the next repodata */ - nextdata = 0; - for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) + if (ndone >= repo->nsolvables) + break; + if (!repodata_precheck_keyname(data, SOLVABLE_FILELIST)) + continue; + for (j = 1; j < data->nkeys; j++) + if (data->keys[j].name == SOLVABLE_FILELIST) + break; + if (j == data->nkeys) + continue; + if (repodata_lookup_idarray(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &fileprovidesq)) { - if (p >= data->end) - continue; - if (data->state != REPODATA_AVAILABLE) - continue; - for (j = 1; j < data->nkeys; j++) - if (data->keys[j].name == REPOSITORY_ADDEDFILEPROVIDES && data->keys[j].type == REPOKEY_TYPE_IDARRAY) + 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 (j == data->nkeys) - continue; - /* great, this repodata contains addedfileprovides */ - if (!nextdata || nextdata->start > data->start) - nextdata = data; - if (p >= data->start) - 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 (i == repo->nrepodata) - data = nextdata; /* no direct hit, use next repodata */ - if (data) + else { - map_empty(&providedids); - repodata_search(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, 0, addfileprovides_setid_cb, &providedids); - for (i = 0; i < cbd->nfiles; i++) - if (!MAPTST(&providedids, cbd->ids[i])) - break; - dataincludes = i == cbd->nfiles; + if (data->start < provstart || data->end > provend) + { + map_empty(&cbd->providedids); + provstart = provend = 0; + } } - oldrepo = repo; - } - if (data && p >= data->start && dataincludes) - continue; - if (ffldata == 0 || p < ffldata->start || p >= ffldata->end) - { - for (i = 0, ffldata = repo->repodata; i < repo->nrepodata; i++, ffldata++) - if (p >= ffldata->start && p < ffldata->end) - break; - if (i == repo->nrepodata) - ffldata = 0; - flags = 0; - if (ffldata) + + /* check if the data is incomplete */ + incomplete = 0; + if (data->state == REPODATA_AVAILABLE) { - for (i = 0; i < cbd->nfiles; i++) + 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 (data && p >= data->start && MAPTST(&providedids, cbd->ids[i])) - continue; - if (!repodata_filelistfilter_matches(ffldata, id2str(pool, cbd->ids[i]))) - { - #if 0 - printf("Need the complete filelist in repo %s because of %s\n", repo->name, id2str(pool, cbd->ids[i])); - #endif - flags = SEARCH_COMPLETE_FILELIST; + for (i = 0; i < cbd->nfiles; i++) + if (!MAPTST(&cbd->providedids, cbd->ids[i]) && !repodata_filelistfilter_matches(data, 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); } - repo_search(repo, p, SOLVABLE_FILELIST, 0, flags, addfileprovides_cb, cbd); + + if (repoonly || ++repoid == pool->nrepos) + break; + repo = pool->repos[repoid]; } - map_free(&providedids); + map_free(&donemap); + queue_free(&fileprovidesq); + map_free(&cbd->providedids); } void @@ -1069,7 +1080,6 @@ pool_addfileprovides_ids(Pool *pool, Repo *installed, Id **idp) map_free(&isf.seen); POOL_DEBUG(SAT_DEBUG_STATS, "found %d file dependencies, %d installed file dependencies\n", sf.nfiles, isf.nfiles); cbd.dids = 0; - map_init(&cbd.useddirs, 1); if (idp) *idp = 0; if (sf.nfiles) @@ -1112,7 +1122,6 @@ pool_addfileprovides_ids(Pool *pool, Repo *installed, Id **idp) sat_free(isf.dirs); sat_free(isf.names); } - map_free(&cbd.useddirs); sat_free(cbd.dids); pool_freewhatprovides(pool); /* as we have added provides */ POOL_DEBUG(SAT_DEBUG_STATS, "addfileprovides took %d ms\n", sat_timems(now)); diff --git a/src/repodata.c b/src/repodata.c index dce3e023..28c3ca41 100644 --- a/src/repodata.c +++ b/src/repodata.c @@ -642,6 +642,27 @@ repodata_lookup_bin_checksum(Repodata *data, Id solvid, Id keyname, Id *typep) return dp; } +int +repodata_lookup_idarray(Repodata *data, Id solvid, Id keyname, Queue *q) +{ + unsigned char *dp; + Repokey *key; + Id id; + int eof = 0; + + queue_empty(q); + dp = find_key_data(data, solvid, keyname, &key); + if (!dp) + return 0; + for (;;) + { + dp = data_read_ideof(dp, &id, &eof); + queue_push(q, id); + if (eof) + break; + } + return 1; +} /************************************************************************ * data search diff --git a/src/repodata.h b/src/repodata.h index a224ad7a..a7c59208 100644 --- a/src/repodata.h +++ b/src/repodata.h @@ -172,7 +172,7 @@ const char *repodata_lookup_str(Repodata *data, Id solvid, Id keyname); int repodata_lookup_num(Repodata *data, Id solvid, Id keyname, unsigned int *value); int repodata_lookup_void(Repodata *data, Id solvid, Id keyname); const unsigned char *repodata_lookup_bin_checksum(Repodata *data, Id solvid, Id keyname, Id *typep); - +int repodata_lookup_idarray(Repodata *data, Id solvid, Id keyname, Queue *q); /*----- diff --git a/src/solver.c b/src/solver.c index 0aaa3c6e..842ad6be 100644 --- a/src/solver.c +++ b/src/solver.c @@ -1352,11 +1352,12 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) /* * here's the main loop: - * 1) propagate new decisions (only needed for level 1) - * 2) try to keep installed packages - * 3) fulfill all unresolved rules - * 4) install recommended packages - * 5) minimalize solution if we had choices + * 1) propagate new decisions (only needed once) + * 2) fulfill jobs + * 3) try to keep installed packages + * 4) fulfill all unresolved rules + * 5) install recommended packages + * 6) minimalize solution if we had choices * if we encounter a problem, we rewind to a safe level and restart * with step 1 */ @@ -1365,7 +1366,7 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) for (;;) { /* - * propagate + * initial propagation of the assertions */ if (level == 1) { @@ -1380,6 +1381,9 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) } } + /* + * resolve jobs first + */ if (level < systemlevel) { POOL_DEBUG(SAT_DEBUG_SOLVER, "resolving job rules\n"); @@ -1439,7 +1443,6 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) /* * installed packages */ - if (level < systemlevel && solv->installed && solv->installed->nsolvables && !solv->installed->disabled) { Repo *installed = solv->installed; @@ -1582,7 +1585,6 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) /* * decide */ - POOL_DEBUG(SAT_DEBUG_POLICY, "deciding unresolved rules\n"); for (i = 1, n = 1; n < solv->nrules; i++, n++) { @@ -1668,6 +1670,8 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) if (n != solv->nrules) /* ran into trouble, restart */ continue; + /* at this point we have a consistent system. now do the extras... */ + if (doweak) { int qcount; @@ -1916,7 +1920,7 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) } map_free(&dqmap); - continue; /* back to main loop */ + continue; /* back to main loop so that all deps are checked */ } } @@ -1947,7 +1951,7 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) break; } if (installedone || i < solv->orphaned.count) - continue; + continue; /* back to main loop */ } if (solv->solution_callback) @@ -2027,12 +2031,13 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) queue_free(&dqs); return; } - continue; + continue; /* back to main loop */ } } /* no minimization found, we're finally finished! */ break; } + POOL_DEBUG(SAT_DEBUG_STATS, "solver statistics: %d learned rules, %d unsolvable, %d minimization steps\n", solv->stats_learned, solv->stats_unsolvable, minimizationsteps); POOL_DEBUG(SAT_DEBUG_STATS, "done solving.\n\n");