diff options
author | Michael Schroeder <mls@suse.de> | 2012-12-17 14:18:18 +0100 |
---|---|---|
committer | Michael Schroeder <mls@suse.de> | 2012-12-17 14:18:18 +0100 |
commit | 235ac170f54880fb1d89cf88a331489e5836af17 (patch) | |
tree | 776bcb6da13d034432b15262369373b96fc90741 | |
parent | abb96ce2e2deba4667f9d42b808939541e692a07 (diff) | |
download | libsolv-235ac170f54880fb1d89cf88a331489e5836af17.tar.gz libsolv-235ac170f54880fb1d89cf88a331489e5836af17.tar.bz2 libsolv-235ac170f54880fb1d89cf88a331489e5836af17.zip |
find_problemrule: don't look at the learnt rule multiple times, it may take really long with some jobs
This basically repeats what's already done in analyze_unsolvable.
-rw-r--r-- | src/problems.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/problems.c b/src/problems.c index 78911f9..fe3f2a2 100644 --- a/src/problems.c +++ b/src/problems.c @@ -844,7 +844,7 @@ solver_take_solution(Solver *solv, Id problem, Id solution, Queue *job) */ static void -findproblemrule_internal(Solver *solv, Id idx, Id *reqrp, Id *conrp, Id *sysrp, Id *jobrp) +findproblemrule_internal(Solver *solv, Id idx, Id *reqrp, Id *conrp, Id *sysrp, Id *jobrp, Map *rseen) { Id rid, d; Id lreqr, lconr, lsysr, ljobr; @@ -873,7 +873,12 @@ findproblemrule_internal(Solver *solv, Id idx, Id *reqrp, Id *conrp, Id *sysrp, { assert(rid > 0); if (rid >= solv->learntrules) - findproblemrule_internal(solv, solv->learnt_why.elements[rid - solv->learntrules], &lreqr, &lconr, &lsysr, &ljobr); + { + if (MAPTST(rseen, rid - solv->learntrules)) + continue; + MAPSET(rseen, rid - solv->learntrules); + findproblemrule_internal(solv, solv->learnt_why.elements[rid - solv->learntrules], &lreqr, &lconr, &lsysr, &ljobr, rseen); + } else if ((rid >= solv->jobrules && rid < solv->jobrules_end) || (rid >= solv->infarchrules && rid < solv->infarchrules_end) || (rid >= solv->duprules && rid < solv->duprules_end) || (rid >= solv->bestrules && rid < solv->bestrules_end)) { if (!*jobrp) @@ -949,8 +954,11 @@ solver_findproblemrule(Solver *solv, Id problem) { Id reqr, conr, sysr, jobr; Id idx = solv->problems.elements[2 * problem - 2]; + Map rseen; reqr = conr = sysr = jobr = 0; - findproblemrule_internal(solv, idx, &reqr, &conr, &sysr, &jobr); + map_init(&rseen, solv->learntrules ? solv->nrules - solv->learntrules : 0); + findproblemrule_internal(solv, idx, &reqr, &conr, &sysr, &jobr, &rseen); + map_free(&rseen); if (reqr) return reqr; /* some requires */ if (conr) @@ -966,14 +974,17 @@ solver_findproblemrule(Solver *solv, Id problem) /*-------------------------------------------------------------------*/ static void -findallproblemrules_internal(Solver *solv, Id idx, Queue *rules) +findallproblemrules_internal(Solver *solv, Id idx, Queue *rules, Map *rseen) { Id rid; while ((rid = solv->learnt_pool.elements[idx++]) != 0) { if (rid >= solv->learntrules) { - findallproblemrules_internal(solv, solv->learnt_why.elements[rid - solv->learntrules], rules); + if (MAPTST(rseen, rid - solv->learntrules)) + continue; + MAPSET(rseen, rid - solv->learntrules); + findallproblemrules_internal(solv, solv->learnt_why.elements[rid - solv->learntrules], rules, rseen); continue; } queue_pushunique(rules, rid); @@ -991,8 +1002,11 @@ findallproblemrules_internal(Solver *solv, Id idx, Queue *rules) void solver_findallproblemrules(Solver *solv, Id problem, Queue *rules) { + Map rseen; queue_empty(rules); - findallproblemrules_internal(solv, solv->problems.elements[2 * problem - 2], rules); + map_init(&rseen, solv->learntrules ? solv->nrules - solv->learntrules : 0); + findallproblemrules_internal(solv, solv->problems.elements[2 * problem - 2], rules, &rseen); + map_free(&rseen); } /* EOF */ |