Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Implement assumptions setup in the solver.
Vsevolod Stakhov committed 10 years ago
commit 0d3849d300b2aed0d45fe07cc9316b81fabf7b3c
parent 76aa6d1
3 files changed +77 -1
modified libpkg/pkg_jobs_universe.c
@@ -939,7 +939,7 @@ pkg_jobs_universe_select_same_repo(struct pkg_job_universe_item *chain,
	return (res);
}

-
static struct pkg_job_universe_item *
+
struct pkg_job_universe_item *
pkg_jobs_universe_select_candidate(struct pkg_job_universe_item *chain,
	struct pkg_job_universe_item *local, bool conservative)
{
modified libpkg/pkg_solve.c
@@ -920,6 +920,71 @@ pkg_solve_picosat_iter(struct pkg_solve_problem *problem, int iter)
	return (res);
}

+
static void
+
pkg_solve_set_initial_assumption(struct pkg_solve_problem *problem,
+
		struct pkg_solve_rule *rule)
+
{
+
	struct pkg_job_universe_item *selected, *cur, *local, *first;
+
	struct pkg_solve_item *item;
+
	struct pkg_solve_variable *var;
+
	bool conservative = false;
+

+
	conservative = pkg_object_bool(pkg_config_get("CONSERVATIVE_UPGRADE"));
+

+
	switch (rule->reason) {
+
	case PKG_RULE_DEPEND:
+
		/*
+
		 * The first item is dependent item, the next items are
+
		 * dependencies. We assume that all deps belong to a single
+
		 * upgrade chain.
+
		 */
+
		assert (rule->items != NULL);
+
		item = rule->items->next;
+
		assert (item != NULL);
+
		var = item->var;
+
		first = var->unit;
+

+
		/* Rewind chain */
+
		while (first->prev->next != NULL) {
+
			first = first->prev;
+
		}
+
		/* Forward chain to find local package */
+
		local = NULL;
+

+
		DL_FOREACH (first, cur) {
+
			if (cur->pkg->type == PKG_INSTALLED) {
+
				local = cur;
+
				break;
+
			}
+
		}
+

+
		selected = pkg_jobs_universe_select_candidate(first, local, conservative);
+
		/* Now we can find the according var */
+
		if (selected != NULL) {
+
			while (var->prev->next != NULL) {
+
				var = var->prev;
+
			}
+
			while (var != NULL) {
+
				if (var->unit == selected) {
+
					picosat_set_default_phase_lit(problem->sat, var->order, 1);
+
					pkg_debug(2, "solver: assumed %s-%s(%s) to be installed",
+
							selected->pkg->name, selected->pkg->version,
+
							selected->pkg->type == PKG_INSTALLED ? "l" : "r");
+
					break;
+
				}
+
				var = var->next;
+
			}
+
		}
+
		break;
+
	case PKG_RULE_REQUIRE:
+
		/* XXX: deal with require rules somehow */
+
		break;
+
	default:
+
		/* No nothing */
+
		return;
+
	}
+
}
+

int
pkg_solve_sat_problem(struct pkg_solve_problem *problem)
{
@@ -931,9 +996,12 @@ pkg_solve_sat_problem(struct pkg_solve_problem *problem)

	for (i = 0; i < kv_size(problem->rules); i++) {
		rule = kv_A(problem->rules, i);
+

		LL_FOREACH(rule->items, item) {
			picosat_add(problem->sat, item->var->order * item->inverse);
		}
+

+
		pkg_solve_set_initial_assumption(problem, rule);
		picosat_add(problem->sat, 0);
		pkg_debug_print_rule(rule);
	}
modified libpkg/private/pkg_jobs.h
@@ -249,6 +249,14 @@ pkg_jobs_universe_get_upgrade_candidates(struct pkg_jobs_universe *universe,
	const char *uid, struct pkg *lp, bool force);

/*
+
 * Among a set of job candidates, select the most matching one, depending on job
+
 * type, repos priorities and other stuff
+
 */
+
struct pkg_job_universe_item *
+
pkg_jobs_universe_select_candidate(struct pkg_job_universe_item *chain,
+
	struct pkg_job_universe_item *local, bool conservative);
+

+
/*
 * Free job request (with all candidates)
 */
void pkg_jobs_request_free(struct pkg_job_request *req);