Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Merge branch 'conflicts-solver'
Vsevolod Stakhov committed 10 years ago
commit c574993cee652a92201f02003f3a043567d080d6
parent cabe8be
3 files changed +125 -111
modified libpkg/pkg_jobs_conflicts.c
@@ -176,14 +176,18 @@ pkg_conflicts_register(struct pkg *p1, struct pkg *p2, enum pkg_conflict_type ty
		if (test == NULL) {
			c1->uid = strdup(p2->uid);
			HASH_ADD_KEYPTR(hh, p1->conflicts, c1->uid, strlen(c1->uid), c1);
-
			pkg_debug(2, "registering conflict between %s and %s", p1->uid, p2->uid);
+
			pkg_debug(2, "registering conflict between %s(%s) and %s(%s)",
+
					p1->uid, p1->type == PKG_INSTALLED ? "l" : "r",
+
					p2->uid, p2->type == PKG_INSTALLED ? "l" : "r");
		}

		HASH_FIND_STR(p2->conflicts, p1->uid, test);
		if (test == NULL) {
			c1->uid = strdup(p1->uid);
			HASH_ADD_KEYPTR(hh, p2->conflicts, c2->uid, strlen(c2->uid), c2);
-
			pkg_debug(2, "registering conflict between %s and %s", p2->uid, p1->uid);
+
			pkg_debug(2, "registering conflict between %s(%s) and %s(%s)",
+
					p2->uid, p2->type == PKG_INSTALLED ? "l" : "r",
+
					p1->uid, p1->type == PKG_INSTALLED ? "l" : "r");
		}
	}
}
@@ -205,7 +209,7 @@ pkg_conflicts_need_conflict(struct pkg_jobs *j, struct pkg *p1, struct pkg *p2)
{
	struct pkg_file *fcur, *ftmp, *ff;
	struct pkg_dir *df;
-
	struct pkg_conflict *c;
+
	struct pkg_conflict *c1, *c2;

	if (pkgdb_ensure_loaded(j->db, p1, PKG_LOAD_FILES|PKG_LOAD_DIRS) != EPKG_OK ||
			pkgdb_ensure_loaded(j->db, p2, PKG_LOAD_FILES|PKG_LOAD_DIRS)
@@ -223,8 +227,9 @@ pkg_conflicts_need_conflict(struct pkg_jobs *j, struct pkg *p1, struct pkg *p2)
	/*
	 * Check if we already have this conflict registered
	 */
-
	HASH_FIND_STR(p1->conflicts, p2->uid, c);
-
	if (c != NULL)
+
	HASH_FIND_STR(p1->conflicts, p2->uid, c1);
+
	HASH_FIND_STR(p2->conflicts, p1->uid, c2);
+
	if (c1 != NULL && c2 != NULL)
		return false;

	/*
@@ -255,22 +260,39 @@ pkg_conflicts_register_unsafe(struct pkg *p1, struct pkg *p2,
{
	struct pkg_conflict *c1, *c2;

-
	pkg_conflict_new(&c1);
-
	pkg_conflict_new(&c2);
-
	c1->type = c2->type = type;
-
	c1->uid = strdup(p2->uid);
-
	c2->uid = strdup(p2->uid);
-

-
	if (use_digest) {
-
		/* We also add digest information into account */
-
		c1->digest = strdup(p2->digest);
-
		c2->digest = strdup(p1->digest);
+
	HASH_FIND_STR(p1->conflicts, p2->uid, c1);
+
	HASH_FIND_STR(p2->conflicts, p1->uid, c2);
+

+
	if (c1 == NULL) {
+
		pkg_conflict_new(&c1);
+
		c1->type = type;
+
		c1->uid = strdup(p2->uid);
+

+
		if (use_digest) {
+
			c1->digest = strdup(p2->digest);
+
		}
+

+
		HASH_ADD_KEYPTR(hh, p1->conflicts, c1->uid, strlen(c1->uid), c1);
+
	}
+

+
	if (c2 == NULL) {
+
		pkg_conflict_new(&c2);
+
		c2->type = type;
+

+
		c2->uid = strdup(p1->uid);
+

+
		if (use_digest) {
+
			/* We also add digest information into account */
+

+
			c2->digest = strdup(p1->digest);
+
		}
+

+
		HASH_ADD_KEYPTR(hh, p2->conflicts, c2->uid, strlen(c2->uid), c2);
	}

-
	HASH_ADD_KEYPTR(hh, p1->conflicts, c1->uid, strlen(c1->uid), c1);
-
	HASH_ADD_KEYPTR(hh, p2->conflicts, c2->uid, strlen(c1->uid), c2);
-
	pkg_debug(2, "registering conflict between %s and %s on path %s",
-
		p1->uid, p2->uid, path);
+
	pkg_debug(2, "registering conflict between %s(%s) and %s(%s) on path %s",
+
			p1->uid, p1->type == PKG_INSTALLED ? "l" : "r",
+
			p2->uid, p2->type == PKG_INSTALLED ? "l" : "r", path);
}

/*
modified libpkg/pkg_jobs_universe.c
@@ -336,14 +336,12 @@ pkg_jobs_universe_handle_provide(struct pkg_jobs_universe *universe,
		/* Check for local packages */
		HASH_FIND_STR(universe->items, rpkg->uid, unit);
		if (unit != NULL) {
-
			if (pkg_jobs_need_upgrade (rpkg, unit->pkg)) {
-
				/* Remote provide is newer, so we can add it */
-
				if (pkg_jobs_universe_process_item(universe, rpkg,
-
						&unit) != EPKG_OK)
-
					continue;
+
			/* Remote provide is newer, so we can add it */
+
			if (pkg_jobs_universe_process_item(universe, rpkg,
+
					&unit) != EPKG_OK)
+
				continue;

-
				rpkg = NULL;
-
			}
+
			rpkg = NULL;
		}
		else {
			/* Maybe local package has just been not added */
@@ -353,12 +351,9 @@ pkg_jobs_universe_handle_provide(struct pkg_jobs_universe *universe,
						&unit) != EPKG_OK) {
					return (EPKG_FATAL);
				}
-
				if (pkg_jobs_need_upgrade (rpkg, npkg)) {
-
					/* Remote provide is newer, so we can add it */
-
					if (pkg_jobs_universe_process_item(universe, rpkg,
-
							&unit) != EPKG_OK)
-
						continue;
-
				}
+
				if (pkg_jobs_universe_process_item(universe, rpkg,
+
						&unit) != EPKG_OK)
+
					continue;
			}
		}

@@ -372,17 +367,11 @@ pkg_jobs_universe_handle_provide(struct pkg_jobs_universe *universe,
					return (EPKG_FATAL);
				}
			}
-
			HASH_FIND_STR(universe->seen, rpkg->digest, seen);
-
			if (seen == NULL) {
-
				pkg_jobs_universe_process_item(universe, rpkg,
-
						&unit);
+
			pkg_jobs_universe_process_item(universe, rpkg,
+
					&unit);

-
				/* Reset package to avoid freeing */
-
				rpkg = NULL;
-
			}
-
			else {
-
				unit = seen->un;
-
			}
+
			/* Reset package to avoid freeing */
+
			rpkg = NULL;
		}

		pr = calloc (1, sizeof (*pr));
modified libpkg/pkg_solve.c
@@ -446,7 +446,6 @@ pkg_solve_add_conflict_rule(struct pkg_solve_problem *problem,
			if (other->type == PKG_INSTALLED)
				continue;
		}
-

		/*
		 * Also if a conflict is digest specific then we skip
		 * variables with mismatched digests
@@ -1085,12 +1084,15 @@ reiterate:

			for (i = 0; i < kv_size(problem->rules); i++) {
				rule = kv_A(problem->rules, i);
-
				LL_FOREACH(rule->items, item) {
-
					if (item->var == var) {
-
						pkg_print_rule_sbuf(rule, sb);
-
						sbuf_putc(sb, '\n');
+

+
				if (rule->reason != PKG_RULE_DEPEND) {
+
					LL_FOREACH(rule->items, item) {
+
						if (item->var == var) {
+
							pkg_print_rule_sbuf(rule, sb);
+
							sbuf_putc(sb, '\n');
+
							break;
+
						}
					}
-
					break;
				}
			}

@@ -1099,83 +1101,80 @@ reiterate:
			sbuf_finish(sb);

			if (pkg_emit_query_yesno(true, sbuf_data(sb))) {
-
				struct pkg_job_request *req;
-
				/* Remove this assumption and the corresponding request */
-
				if (var->flags & PKG_VAR_INSTALL)
-
					HASH_FIND_PTR(problem->j->request_add, &var->unit, req);
-
				else
-
					HASH_FIND_PTR(problem->j->request_delete, &var->unit, req);
-
				if (req == NULL) {
-
					pkg_emit_error("cannot find %s in the request", var->uid);
-
					return (EPKG_FATAL);
-
				}
-

-
				if (var->flags & PKG_VAR_INSTALL)
-
					HASH_DEL(problem->j->request_add, req);
-
				else
-
					HASH_DEL(problem->j->request_delete, req);
-
				sbuf_reset(sb);
-
			}
-
			else {
-
				sbuf_free(sb);
-
				return (EPKG_FATAL);
+
				var->flags |= PKG_VAR_FAILED;
			}

+
			sbuf_reset(sb);
+

			failed ++;
+
			need_reiterate = true;
		}

		sbuf_free(sb);
+
#if 0
+
		failed = picosat_next_maximal_satisfiable_subset_of_assumptions(problem->sat);

-
		return (EPKG_AGAIN);
-
	}
+
		while (*failed) {
+
			struct pkg_solve_variable *var = &problem->variables[*failed - 1];

-
	/* Assign vars */
-
	for (i = 0; i < problem->nvars; i ++) {
-
		int val = picosat_deref(problem->sat, i + 1);
-
		struct pkg_solve_variable *var = &problem->variables[i];
-

-
		if (val > 0)
-
			var->flags |= PKG_VAR_INSTALL;
-
		else
-
			var->flags &= ~PKG_VAR_INSTALL;
-

-
		pkg_debug(2, "decided %s %s-%s to %s",
-
			var->unit->pkg->type == PKG_INSTALLED ? "local" : "remote",
-
			var->uid, var->digest,
-
			var->flags & PKG_VAR_INSTALL ? "install" : "delete");
+
			pkg_emit_notice("var: %s", var->uid);
+

+
			failed ++;
+
		}
+

+
		return (EPKG_AGAIN);
+
#endif
	}
+
	else {

-
	/* Check for reiterations */
-
	if ((problem->j->type == PKG_JOBS_INSTALL ||
-
			problem->j->type == PKG_JOBS_UPGRADE) && iter == 0) {
+
		/* Assign vars */
		for (i = 0; i < problem->nvars; i ++) {
-
			bool failed_var = false;
-
			struct pkg_solve_variable *var = &problem->variables[i], *cur;
-

-
			if (!(var->flags & PKG_VAR_INSTALL)) {
-
				LL_FOREACH(var, cur) {
-
					if (cur->flags & PKG_VAR_INSTALL) {
-
						failed_var = false;
-
						break;
-
					}
-
					else if (cur->unit->pkg->type == PKG_INSTALLED) {
-
						failed_var = true;
+
			int val = picosat_deref(problem->sat, i + 1);
+
			struct pkg_solve_variable *var = &problem->variables[i];
+

+
			if (val > 0)
+
				var->flags |= PKG_VAR_INSTALL;
+
			else
+
				var->flags &= ~PKG_VAR_INSTALL;
+

+
			pkg_debug(2, "decided %s %s-%s to %s",
+
					var->unit->pkg->type == PKG_INSTALLED ? "local" : "remote",
+
							var->uid, var->digest,
+
							var->flags & PKG_VAR_INSTALL ? "install" : "delete");
+
		}
+

+
		/* Check for reiterations */
+
		if ((problem->j->type == PKG_JOBS_INSTALL ||
+
				problem->j->type == PKG_JOBS_UPGRADE) && iter == 0) {
+
			for (i = 0; i < problem->nvars; i ++) {
+
				bool failed_var = false;
+
				struct pkg_solve_variable *var = &problem->variables[i], *cur;
+

+
				if (!(var->flags & PKG_VAR_INSTALL)) {
+
					LL_FOREACH(var, cur) {
+
						if (cur->flags & PKG_VAR_INSTALL) {
+
							failed_var = false;
+
							break;
+
						}
+
						else if (cur->unit->pkg->type == PKG_INSTALLED) {
+
							failed_var = true;
+
						}
					}
				}
-
			}
-

-
			/*
-
			 * If we want to delete local packages on installation, do one more SAT
-
			 * iteration to ensure that we have no other choices
-
			 */
-
			if (failed_var) {
-
				pkg_debug (1, "trying to delete local package %s-%s on install/upgrade,"
-
					" reiterate on SAT",
-
					var->unit->pkg->name, var->unit->pkg->version);
-
				need_reiterate = true;

-
				LL_FOREACH(var, cur) {
-
					cur->flags |= PKG_VAR_FAILED;
+
				/*
+
				 * If we want to delete local packages on installation, do one more SAT
+
				 * iteration to ensure that we have no other choices
+
				 */
+
				if (failed_var) {
+
					pkg_debug (1, "trying to delete local package %s-%s on install/upgrade,"
+
							" reiterate on SAT",
+
							var->unit->pkg->name, var->unit->pkg->version);
+
					need_reiterate = true;
+

+
					LL_FOREACH(var, cur) {
+
						cur->flags |= PKG_VAR_FAILED;
+
					}
				}
			}
		}
@@ -1189,6 +1188,10 @@ reiterate:
			struct pkg_solve_variable *var = &problem->variables[i];

			if (var->flags & PKG_VAR_TOP) {
+
				if (var->flags & PKG_VAR_FAILED) {
+
					var->flags ^= PKG_VAR_INSTALL | PKG_VAR_FAILED;
+
				}
+

				picosat_assume(problem->sat, var->order *
						(var->flags & PKG_VAR_INSTALL ? 1 : -1));
			}