From: Michael Schroeder Date: Fri, 11 Jan 2013 12:54:53 +0000 (+0100) Subject: support "pooljobs", fixed jobs set in the pool X-Git-Tag: BASE-SuSE-Code-12_3-Branch~103 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b746354f4cd0ef51a155241369de1f804f5f756c;p=thirdparty%2Flibsolv.git support "pooljobs", fixed jobs set in the pool Those are normally jobs like USERINSTALLED or NOOBSOLETES. --- diff --git a/bindings/solv.i b/bindings/solv.i index 3273b349..16564ff1 100644 --- a/bindings/solv.i +++ b/bindings/solv.i @@ -1329,6 +1329,49 @@ typedef struct { sel->flags = selection_make($self, &sel->q, name, flags); return sel; } + + void setpooljobs_helper(Queue jobs) { + queue_free(&$self->pooljobs); + queue_init_clone(&$self->pooljobs, &jobs); + } + %typemap(out) Queue getpooljobs Queue2Array(Job *, 2, new_Job(arg1, id, idp[1])); + %newobject getpooljobs; + Queue getpooljobs() { + Queue q; + queue_init_clone(&q, &$self->pooljobs); + return q; + } + +#if defined(SWIGPYTHON) + %pythoncode { + def setpooljobs(self, jobs): + j = [] + for job in jobs: j += [job.how, job.what] + self.setpooljobs_helper(j) + } +#endif +#if defined(SWIGPERL) + %perlcode { + sub solv::Solver::setpooljobs { + my ($self, $jobs) = @_; + my @j = map {($_->{'how'}, $_->{'what'})} @$jobs; + return $self->setpooljobs_helper(\@j); + } + } +#endif +#if defined(SWIGRUBY) +%init %{ +rb_eval_string( + "class Solv::Pool\n" + " def setpooljobs(jobs)\n" + " jl = []\n" + " jobs.each do |j| ; jl << j.how << j.what ; end\n" + " setpooljobs_helper(jl)\n" + " end\n" + "end\n" + ); +%} +#endif } %extend Repo { @@ -2466,6 +2509,7 @@ typedef struct { static const int SOLVER_RULE_LEARNT = SOLVER_RULE_LEARNT; static const int SOLVER_SOLUTION_JOB = SOLVER_SOLUTION_JOB; + static const int SOLVER_SOLUTION_POOLJOB = SOLVER_SOLUTION_POOLJOB; static const int SOLVER_SOLUTION_INFARCH = SOLVER_SOLUTION_INFARCH; static const int SOLVER_SOLUTION_DISTUPGRADE = SOLVER_SOLUTION_DISTUPGRADE; static const int SOLVER_SOLUTION_BEST = SOLVER_SOLUTION_BEST; diff --git a/src/pool.c b/src/pool.c index 0f7c9287..d8eb0402 100644 --- a/src/pool.c +++ b/src/pool.c @@ -103,6 +103,7 @@ pool_free(Pool *pool) solv_free(pool->rels); pool_setvendorclasses(pool, 0); queue_free(&pool->vendormap); + queue_free(&pool->pooljobs); for (i = 0; i < POOL_TMPSPACEBUF; i++) solv_free(pool->tmpspace.buf[i]); for (i = 0; i < pool->nlanguages; i++) diff --git a/src/pool.h b/src/pool.h index cb838007..97224e08 100644 --- a/src/pool.h +++ b/src/pool.h @@ -119,6 +119,8 @@ struct _Pool { /* search position */ Datapos pos; + Queue pooljobs; /* fixed jobs, like USERINSTALLED/NOOBSOLETES */ + #ifdef LIBSOLV_INTERNAL /* flags to tell the library how the installed package manager works */ int promoteepoch; /* true: missing epoch is replaced by epoch of dependency */ diff --git a/src/problems.c b/src/problems.c index fe3f2a24..11db5feb 100644 --- a/src/problems.c +++ b/src/problems.c @@ -260,7 +260,7 @@ refine_suggestion(Solver *solv, Id *problem, Id sug, Queue *refined, int essenti nupdate++; else { - if (!essentialok && (solv->job.elements[-v -1] & SOLVER_ESSENTIAL) != 0) + if (!essentialok && (solv->job.elements[-v - 1] & SOLVER_ESSENTIAL) != 0) continue; /* not that one! */ njob++; } @@ -382,8 +382,17 @@ convertsolution(Solver *solv, Id why, Queue *solutionq) Pool *pool = solv->pool; if (why < 0) { - queue_push(solutionq, 0); - queue_push(solutionq, -why); + why = -why; + if (why < solv->pooljobcnt) + { + queue_push(solutionq, SOLVER_SOLUTION_POOLJOB); + queue_push(solutionq, why); + } + else + { + queue_push(solutionq, SOLVER_SOLUTION_JOB); + queue_push(solutionq, why - solv->pooljobcnt); + } return; } if (why >= solv->infarchrules && why < solv->infarchrules_end) @@ -775,6 +784,8 @@ solver_solutionelement_extrajobflags(Solver *solv, Id problem, Id solution) * -> add (SOLVER_INSTALL|SOLVER_SOLVABLE, rp) to the job * SOLVER_SOLUTION_JOB jobidx * -> remove job (jobidx - 1, jobidx) from job queue + * SOLVER_SOLUTION_POOLJOB jobidx + * -> remove job (jobidx - 1, jobidx) from pool job queue * pkgid (> 0) 0 * -> add (SOLVER_ERASE|SOLVER_SOLVABLE, p) to the job * pkgid (> 0) pkgid (> 0) @@ -807,6 +818,12 @@ solver_take_solutionelement(Solver *solv, Id p, Id rp, Id extrajobflags, Queue * { int i; + if (p == SOLVER_SOLUTION_POOLJOB) + { + solv->pool->pooljobs.elements[rp - 1] = SOLVER_NOOP; + solv->pool->pooljobs.elements[rp] = 0; + return; + } if (p == SOLVER_SOLUTION_JOB) { job->elements[rp - 1] = SOLVER_NOOP; diff --git a/src/problems.h b/src/problems.h index cb371394..4f5021f9 100644 --- a/src/problems.h +++ b/src/problems.h @@ -24,6 +24,7 @@ struct _Solver; #define SOLVER_SOLUTION_DISTUPGRADE (-1) #define SOLVER_SOLUTION_INFARCH (-2) #define SOLVER_SOLUTION_BEST (-3) +#define SOLVER_SOLUTION_POOLJOB (-4) void solver_disableproblem(struct _Solver *solv, Id v); void solver_enableproblem(struct _Solver *solv, Id v); diff --git a/src/solver.c b/src/solver.c index 76680cea..2f248398 100644 --- a/src/solver.c +++ b/src/solver.c @@ -2874,6 +2874,13 @@ solver_solve(Solver *solv, Queue *job) /* remember job */ queue_free(&solv->job); queue_init_clone(&solv->job, job); + solv->pooljobcnt = pool->pooljobs.count; + if (pool->pooljobs.count) + { + queue_insertn(&solv->job, 0, pool->pooljobs.count); + memcpy(solv->job.elements, pool->pooljobs.elements, pool->pooljobs.count * sizeof(Id)); + } + job = &solv->job; /* free old stuff */ if (solv->update_targets) @@ -3177,6 +3184,8 @@ solver_solve(Solver *solv, Queue *job) { oldnrules = solv->nrules; + if (i && i == solv->pooljobcnt) + POOL_DEBUG(SOLV_DEBUG_JOB, "end of pool jobs\n"); how = job->elements[i]; what = job->elements[i + 1]; weak = how & SOLVER_WEAK; @@ -3346,10 +3355,10 @@ solver_solve(Solver *solv, Queue *job) { int j; if (solv->nrules == oldnrules) - POOL_DEBUG(SOLV_DEBUG_JOB, " - no rule created\n"); + POOL_DEBUG(SOLV_DEBUG_JOB, " - no rule created\n"); for (j = oldnrules; j < solv->nrules; j++) { - POOL_DEBUG(SOLV_DEBUG_JOB, " - job "); + POOL_DEBUG(SOLV_DEBUG_JOB, " - job "); solver_printrule(solv, SOLV_DEBUG_JOB, solv->rules + j); } } diff --git a/src/solver.h b/src/solver.h index dc7377fc..a1347186 100644 --- a/src/solver.h +++ b/src/solver.h @@ -82,6 +82,8 @@ struct _Solver { */ UpdateCandidateCb updateCandidateCb; + int pooljobcnt; /* number of pooljob entries in job queue */ + #ifdef LIBSOLV_INTERNAL Repo *installed; /* copy of pool->installed */ diff --git a/src/solverdebug.c b/src/solverdebug.c index 58785f76..666401f6 100644 --- a/src/solverdebug.c +++ b/src/solverdebug.c @@ -656,9 +656,11 @@ solver_printsolution(Solver *solv, Id problem, Id solution) element = 0; while ((element = solver_next_solutionelement(solv, problem, solution, element, &p, &rp)) != 0) { - if (p == SOLVER_SOLUTION_JOB) + if (p == SOLVER_SOLUTION_JOB || p == SOLVER_SOLUTION_POOLJOB) { /* job, rp is index into job queue */ + if (p == SOLVER_SOLUTION_JOB) + rp += solv->pooljobcnt; how = solv->job.elements[rp - 1]; what = solv->job.elements[rp]; select = how & SOLVER_SELECTMASK; @@ -1042,10 +1044,13 @@ const char * solver_solutionelement2str(Solver *solv, Id p, Id rp) { Pool *pool = solv->pool; - if (p == SOLVER_SOLUTION_JOB) + if (p == SOLVER_SOLUTION_JOB || p == SOLVER_SOLUTION_POOLJOB) { - Id how = solv->job.elements[rp - 1]; - Id what = solv->job.elements[rp]; + Id how, what; + if (p == SOLVER_SOLUTION_JOB) + rp += solv->pooljobcnt; + how = solv->job.elements[rp - 1]; + what = solv->job.elements[rp]; return pool_tmpjoin(pool, "do not ask to ", pool_job2str(pool, how, what, 0), 0); } else if (p == SOLVER_SOLUTION_INFARCH)