From f6903b67f3728f9c77eb4a2942fe3eb7268737f2 Mon Sep 17 00:00:00 2001 From: Jon Turney Date: Wed, 21 Feb 2018 16:28:48 +0000 Subject: [PATCH setup] Improve default solution selection Pick a solution which looks like it removes non-lock tasks from the task list. This kind of works because lock tasks are usually created from a default keep choice, rather than from an explicit selection, although really we need to track somehow if the task was created from a user choice and use that as the criteria here... --- libsolv.cc | 37 ++++++++++++++++++++++++++++++++++--- libsolv.h | 1 + 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/libsolv.cc b/libsolv.cc index 32d60e6..140ace9 100644 --- a/libsolv.cc +++ b/libsolv.cc @@ -922,8 +922,8 @@ void SolverSolution::applyDefaultProblemSolutions() int pcnt = solver_problem_count(solv); for (Id problem = 1; problem <= pcnt; problem++) { - int scnt = solver_solution_count(solv, problem); - solver_take_solution(solv, problem, scnt, &job); + int default_soln = guessDefaultSolution(problem); + solver_take_solution(solv, problem, default_soln, &job); } // re-solve @@ -937,6 +937,36 @@ SolverSolution::transactions() const return trans; } +// pick a default solution +Id SolverSolution::guessDefaultSolution(Id problem) const +{ + int scnt = solver_solution_count(solv, problem); + + // search backwards for the first solution which only consists of + // SOLVER_SOLUTION_JOB solution elements pointing to SOLVER_INSTALL or + // SOLVER_ERASE jobs (i.e. only removes install or erase tasks from task list) + for (Id solution = scnt; solution > 0; solution--) + { + Id p, rp, element; + element = 0; + while ((element = solver_next_solutionelement(solv, problem, solution, element, &p, &rp)) != 0) + { + if (p != SOLVER_SOLUTION_JOB) + break; + + Id j = job.elements[rp-1] & SOLVER_JOBMASK; + if (!(j == SOLVER_INSTALL || j == SOLVER_ERASE)) + break; + } + + if (element == 0) + return solution; + } + + // failing that, pick the last solution + return scnt; +} + // Construct a string reporting the problems and solutions std::string SolverSolution::report() const @@ -959,10 +989,11 @@ SolverSolution::report() const r += "\n"; int scnt = solver_solution_count(solv, problem); + Id default_soln_id = guessDefaultSolution(problem); for (Id solution = 1; solution <= scnt; solution++) { r += "Solution " + std::to_string(solution) + "/" + std::to_string(scnt); - if (solution == scnt) r += " (default)"; + if (solution == default_soln_id) r += " (default)"; r += "\n"; Id p, rp, element; diff --git a/libsolv.h b/libsolv.h index 6a6e0b3..3066fea 100644 --- a/libsolv.h +++ b/libsolv.h @@ -266,6 +266,7 @@ class SolverSolution bool solve(); void tasksToJobs(SolverTasks &tasks, updateMode update, Queue &job); void solutionToTransactionList(); + Id guessDefaultSolution(Id problem) const; SolverPool &pool; Solver *solv; -- 2.16.2