Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Use universe items instead of packages.
Vsevolod Stakhov committed 12 years ago
commit 4d8932a1bd11ee20773616854423c618eed8c773
parent b7ee21e
5 files changed +90 -171
modified libpkg/pkg_conflicts.c
@@ -49,8 +49,8 @@ pkg_conflicts_chain_cmp_cb(struct pkg_conflict_chain *a, struct pkg_conflict_cha
		return (a->req->skip - b->req->skip);
	}

-
	pkg_get(a->req->pkg, PKG_VERSION, &vera);
-
	pkg_get(b->req->pkg, PKG_VERSION, &verb);
+
	pkg_get(a->req->item->pkg, PKG_VERSION, &vera);
+
	pkg_get(b->req->item->pkg, PKG_VERSION, &verb);

	/* Inverse sort to get the maximum version as the first element */
	return (pkg_version_cmp(vera, verb));
@@ -68,7 +68,7 @@ pkg_conflicts_request_resolve_chain(struct pkg *req, struct pkg_conflict_chain *
	 * an origin is pkg name
	 */
	LL_FOREACH(chain, elt) {
-
		pkg_get(elt->req->pkg, PKG_ORIGIN, &origin);
+
		pkg_get(elt->req->item->pkg, PKG_ORIGIN, &origin);
		slash_pos = strrchr(origin, '/');
		if (slash_pos != NULL) {
			if (strcmp(slash_pos + 1, name) == 0) {
@@ -85,7 +85,7 @@ pkg_conflicts_request_resolve_chain(struct pkg *req, struct pkg_conflict_chain *
		selected = chain;
	}

-
	pkg_get(selected->req->pkg, PKG_ORIGIN, &origin);
+
	pkg_get(selected->req->item->pkg, PKG_ORIGIN, &origin);
	pkg_debug(2, "select %s in the chain of conflicts for %s", origin, name);
	/* Disable conflicts from a request */
	LL_FOREACH(chain, elt) {
@@ -122,18 +122,18 @@ pkg_conflicts_request_resolve(struct pkg_jobs *j)
		if (req->skip)
			continue;

-
		HASH_ITER(hh, req->pkg->conflicts, c, ctmp) {
+
		HASH_ITER(hh, req->item->pkg->conflicts, c, ctmp) {
			HASH_FIND_STR(j->request_add, pkg_conflict_origin(c), found);
			if (found && !found->skip) {
				pkg_conflicts_request_add_chain(&chain, found);
			}
		}
		if (chain != NULL) {
-
			pkg_get(req->pkg, PKG_ORIGIN, &origin);
+
			pkg_get(req->item->pkg, PKG_ORIGIN, &origin);
			/* Add package itself */
			pkg_conflicts_request_add_chain(&chain, req);

-
			if (pkg_conflicts_request_resolve_chain(req->pkg, chain) != EPKG_OK) {
+
			if (pkg_conflicts_request_resolve_chain(req->item->pkg, chain) != EPKG_OK) {
				LL_FREE(chain, pkg_conflict_chain, free);
				return (EPKG_FATAL);
			}
modified libpkg/pkg_cudf.c
@@ -202,7 +202,7 @@ cudf_emit_request_packages(const char *op, struct pkg_jobs *j, FILE *f)
	HASH_ITER(hh, j->request_add, req, tmp) {
		if (req->skip)
			continue;
-
		pkg_get(req->pkg, PKG_ORIGIN, &origin);
+
		pkg_get(req->item->pkg, PKG_ORIGIN, &origin);
		if (cudf_print_element(f, origin,
				(req->hh.next != NULL), &column) < 0) {
			return (EPKG_FATAL);
@@ -221,7 +221,7 @@ cudf_emit_request_packages(const char *op, struct pkg_jobs *j, FILE *f)
	HASH_ITER(hh, j->request_delete, req, tmp) {
		if (req->skip)
			continue;
-
		pkg_get(req->pkg, PKG_ORIGIN, &origin);
+
		pkg_get(req->item->pkg, PKG_ORIGIN, &origin);
		if (cudf_print_element(f, origin,
				(req->hh.next != NULL), &column) < 0) {
			return (EPKG_FATAL);
@@ -356,13 +356,12 @@ pkg_jobs_cudf_insert_res_job (struct pkg_solved **target,
		pkg_emit_errno("calloc", "pkg_solved");
		return;
	}
-
	res->priority = it_new->priority;
-
	res->pkg[0] = it_new->pkg;
+

+
	res->items[0] = it_new;
	res->type = type;
-
	if (it_old != NULL) {
-
		res->pkg[1] = it_old->pkg;
-
		res->priority = MAX(it_old->priority, res->priority);
-
	}
+
	if (it_old != NULL)
+
		res->items[1] = it_old;
+

	DL_APPEND(*target, res);
}

modified libpkg/pkg_jobs.c
@@ -172,15 +172,15 @@ pkg_jobs_iter(struct pkg_jobs *jobs, void **iter,
	else {
		s = *iter;
	}
-
	*new = s->pkg[0];
-
	*old = s->pkg[1];
+
	*new = s->items[0]->pkg;
+
	*old = s->items[1]->pkg;
	*type = s->type;
	*iter = s->next ? s->next : jobs->jobs;
	return (true);
}

static void
-
pkg_jobs_add_req(struct pkg_jobs *j, const char *origin, struct pkg *pkg,
+
pkg_jobs_add_req(struct pkg_jobs *j, const char *origin, struct pkg_job_universe_item *item,
		bool add, int priority)
{
	struct pkg_job_request *req, *test, **head;
@@ -193,28 +193,15 @@ pkg_jobs_add_req(struct pkg_jobs *j, const char *origin, struct pkg *pkg,

	HASH_FIND(hh, *head, origin, strlen(origin), test);

-
	if (test != NULL) {
-
		if (test->priority < priority)
-
			replace = true;
-

-
		pkg_debug(1, "the request already has package with origin %s, we want "
-
				"to %s it by priority (%d) vs (%d)", origin,
-
				replace ? "replace" : "keep",
-
				test->priority, priority);
-
		if (replace) {
-
			test->pkg = pkg;
-
			test->priority = priority;
-
		}
+
	if (test != NULL)
		return;
-
	}

	req = calloc(1, sizeof (struct pkg_job_request));
	if (req == NULL) {
		pkg_emit_errno("malloc", "struct pkg_job_request");
		return;
	}
-
	req->pkg = pkg;
-
	req->priority = priority;
+
	req->item = item;

	HASH_ADD_KEYPTR(hh, *head, origin, strlen(origin), req);
}
@@ -329,7 +316,9 @@ pkg_jobs_handle_pkg_universe(struct pkg_jobs *j, struct pkg *pkg,
					false);
		else if (*priority < cur->priority)
			*priority = cur->priority;
-
		*found = seen->un;
+
		if (found != NULL)
+
			*found = seen->un;
+

		return (EPKG_END);
	}

@@ -367,24 +356,26 @@ pkg_jobs_handle_pkg_universe(struct pkg_jobs *j, struct pkg *pkg,

	j->total++;

-
	*found = item;
+
	if (found != NULL)
+
		*found = item;

	return (EPKG_OK);
}

static int
-
pkg_jobs_add_universe(struct pkg_jobs *j, struct pkg *pkg, int priority, bool recursive)
+
pkg_jobs_add_universe(struct pkg_jobs *j, struct pkg *pkg, int priority,
+
		bool recursive, struct pkg_job_universe_item **result)
{
	struct pkg_dep *d = NULL;
	struct pkg_conflict *c = NULL;
	struct pkg *npkg, *rpkg;
	int ret;
-
	struct pkg_job_universe_item *unit, *local;
+
	struct pkg_job_universe_item *unit;
	const char *origin;
	int maxpri;

	/* Add the requested package itself */
-
	ret = pkg_jobs_handle_pkg_universe(j, pkg, &priority, &local);
+
	ret = pkg_jobs_handle_pkg_universe(j, pkg, &priority, result);

	if (ret == EPKG_END)
		return (EPKG_OK);
@@ -405,7 +396,7 @@ pkg_jobs_add_universe(struct pkg_jobs *j, struct pkg *pkg, int priority, bool re
				rpkg = NULL;
			}
			else {
-
				if (pkg_jobs_add_universe(j, rpkg, priority, recursive) != EPKG_OK)
+
				if (pkg_jobs_add_universe(j, rpkg, priority, recursive, NULL) != EPKG_OK)
					return (EPKG_FATAL);
			}
		}
@@ -450,10 +441,10 @@ pkg_jobs_add_universe(struct pkg_jobs *j, struct pkg *pkg, int priority, bool re
			}
		}
		pkg_set(npkg, PKG_AUTOMATIC, (int64_t)true);
-
		if (pkg_jobs_add_universe(j, npkg, priority + 1, recursive) != EPKG_OK)
+
		if (pkg_jobs_add_universe(j, npkg, priority + 1, recursive, NULL) != EPKG_OK)
			return (EPKG_FATAL);
		if (rpkg != NULL) {
-
			if (pkg_jobs_add_universe(j, rpkg, priority + 1, recursive) != EPKG_OK)
+
			if (pkg_jobs_add_universe(j, rpkg, priority + 1, recursive, NULL) != EPKG_OK)
				return (EPKG_FATAL);
			pkg_set(rpkg, PKG_AUTOMATIC, (int64_t)true);
		}
@@ -484,14 +475,9 @@ pkg_jobs_add_universe(struct pkg_jobs *j, struct pkg *pkg, int priority, bool re
				return (EPKG_FATAL);
			}
		}
-
		if (pkg_jobs_add_universe(j, npkg, maxpri - 1, recursive) != EPKG_OK)
+
		if (pkg_jobs_add_universe(j, npkg, maxpri - 1, recursive, NULL) != EPKG_OK)
			return (EPKG_FATAL);
	}
-
	if (priority != maxpri) {
-
		/* Need to update due to rdeps order */
-
		pkg_jobs_update_universe_priority(j, local, maxpri,
-
							"rdep from universe", false);
-
	}

	/* Examine conflicts */
	while (pkg_conflicts(pkg, &c) == EPKG_OK) {
@@ -506,14 +492,14 @@ pkg_jobs_add_universe(struct pkg_jobs *j, struct pkg *pkg, int priority, bool re

		/* Check both local and remote conflicts */
		npkg = get_remote_pkg(j, pkg_conflict_origin(c), 0);
-
		if (pkg_jobs_add_universe(j, npkg, priority, recursive) != EPKG_OK)
+
		if (pkg_jobs_add_universe(j, npkg, priority, recursive, NULL) != EPKG_OK)
			return (EPKG_FATAL);
		npkg = get_local_pkg(j, pkg_conflict_origin(c), 0);
		if (npkg == NULL) {
			continue;
		}

-
		if (pkg_jobs_add_universe(j, npkg, priority, recursive) != EPKG_OK)
+
		if (pkg_jobs_add_universe(j, npkg, priority, recursive, NULL) != EPKG_OK)
			return (EPKG_FATAL);
	}

@@ -556,7 +542,7 @@ pkg_jobs_test_automatic(struct pkg_jobs *j, struct pkg *p, int priority)
				pkg_free(npkg);
				return (false);
			}
-
			if (pkg_jobs_add_universe(j, npkg, priority - 1, false) != EPKG_OK)
+
			if (pkg_jobs_add_universe(j, npkg, priority - 1, false, NULL) != EPKG_OK)
				return (false);
		}

@@ -594,7 +580,7 @@ new_pkg_version(struct pkg_jobs *j)
		goto end;
	}

-
	pkg_jobs_add_universe(j, p, INT_MAX, true);
+
	pkg_jobs_add_universe(j, p, INT_MAX, true, NULL);

	/* Use maximum priority for pkg */
	if (find_remote_pkg(j, origin, MATCH_EXACT, false, INT_MAX, true) == EPKG_OK) {
@@ -670,10 +656,8 @@ find_remote_pkg(struct pkg_jobs *j, const char *pattern,
		rc = EPKG_OK;
		p->direct = root;
		/* Add a package to request chain and populate universe */
-

-
		pkg_jobs_add_req(j, origin, p, true, priority);
-
		rc = pkg_jobs_add_universe(j, p, priority, recursive);
-

+
		rc = pkg_jobs_add_universe(j, p, priority, recursive, &jit);
+
		pkg_jobs_add_req(j, origin, jit, true, priority);

		p = NULL;
	}
@@ -922,7 +906,7 @@ pkg_conflicts_add_missing(struct pkg_jobs *j, const char *origin, int priority)
		return (EPKG_FATAL);
	}

-
	return pkg_jobs_add_universe(j, npkg, priority, true);
+
	return pkg_jobs_add_universe(j, npkg, priority, true, NULL);
}

/*
@@ -1085,41 +1069,6 @@ pkg_conflicts_integrity_check(struct pkg_jobs *j)
	return (pkgdb_integrity_check(j->db, pkg_conflicts_add_from_pkgdb_local, j));
}

-
static void
-
pkg_jobs_update_request_priorities(struct pkg_jobs *j)
-
{
-
	struct pkg_job_request *req, *rtmp;
-
	struct pkg_job_universe_item *unit, *cur;
-
	const char *origin;
-

-
	/*
-
	 * We update priorities in the universe according to the real
-
	 * dependencies graph, however, priorities in the request are not
-
	 * updated. So we cycle through the request and set the priorities
-
	 * equal to priorities in the universe.
-
	 */
-
	HASH_ITER(hh, j->request_delete, req, rtmp) {
-
		pkg_get(req->pkg, PKG_ORIGIN, &origin);
-
		HASH_FIND_STR(j->universe, origin, unit);
-
		if (unit != NULL) {
-
			LL_FOREACH(unit, cur) {
-
				if (cur->pkg == req->pkg)
-
					req->priority = cur->priority;
-
			}
-
		}
-
	}
-
	HASH_ITER(hh, j->request_add, req, rtmp) {
-
		pkg_get(req->pkg, PKG_ORIGIN, &origin);
-
		HASH_FIND_STR(j->universe, origin, unit);
-
		if (unit != NULL) {
-
			LL_FOREACH(unit, cur) {
-
				if (cur->pkg == req->pkg)
-
					req->priority = cur->priority;
-
			}
-
		}
-
	}
-
}
-

static int
jobs_solve_deinstall(struct pkg_jobs *j)
{
@@ -1127,6 +1076,7 @@ jobs_solve_deinstall(struct pkg_jobs *j)
	struct pkg *pkg = NULL;
	struct pkgdb_it *it;
	char *origin;
+
	struct pkg_job_universe_item *unit;

	bool recursive = false;

@@ -1140,22 +1090,21 @@ jobs_solve_deinstall(struct pkg_jobs *j)
		while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC|PKG_LOAD_RDEPS) == EPKG_OK) {
			// Check if the pkg is locked
			pkg_get(pkg, PKG_ORIGIN, &origin);
+
			pkg_jobs_add_universe(j, pkg, 0, recursive, &unit);
			if(pkg_is_locked(pkg)) {
				pkg_emit_locked(pkg);
			}
			else {
				pkg_get(pkg, PKG_ORIGIN, &origin);
-
				pkg_jobs_add_req(j, origin, pkg, false, 0);
+
				pkg_jobs_add_req(j, origin, unit, false, 0);
			}
			/* TODO: use repository priority here */
-
			pkg_jobs_add_universe(j, pkg, 0, recursive);
+

			pkg = NULL;
		}
		pkgdb_it_free(it);
	}

-
	pkg_jobs_update_request_priorities(j);
-

	j->solved = true;

	return( EPKG_OK);
@@ -1177,16 +1126,15 @@ jobs_solve_autoremove(struct pkg_jobs *j)
		pkg_get(pkg, PKG_ORIGIN, &origin);
		HASH_FIND_STR(j->universe, origin, unit);
		if (unit == NULL) {
+
			pkg_jobs_add_universe(j, pkg, 0, false, &unit);
			if(pkg_is_locked(pkg)) {
				pkg_emit_locked(pkg);
			}
			else if (pkg_jobs_test_automatic(j, pkg, 0)) {
				pkg_debug(2, "removing %s as it has no non-automatic reverse depends",
						origin);
-
				pkg_jobs_add_req(j, origin, pkg, false, 0);
+
				pkg_jobs_add_req(j, origin, unit, false, 0);
			}
-
			/* TODO: use repository priority here */
-
			pkg_jobs_add_universe(j, pkg, 0, false);
		}
		else {
			if(pkg_is_locked(unit->pkg)) {
@@ -1195,7 +1143,7 @@ jobs_solve_autoremove(struct pkg_jobs *j)
			else if (pkg_jobs_test_automatic(j, unit->pkg, unit->priority)) {
				pkg_debug(2, "removing %s as it has no non-automatic reverse depends",
						origin);
-
				pkg_jobs_add_req(j, origin, unit->pkg, false, unit->priority);
+
				pkg_jobs_add_req(j, origin, unit, false, unit->priority);
			}

			pkg_free(pkg);
@@ -1204,7 +1152,6 @@ jobs_solve_autoremove(struct pkg_jobs *j)
	}
	pkgdb_it_free(it);

-
	pkg_jobs_update_request_priorities(j);
	j->solved = true;

	return (EPKG_OK);
@@ -1231,7 +1178,7 @@ jobs_solve_upgrade(struct pkg_jobs *j)

		while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) {
			/* TODO: use repository priority here */
-
			pkg_jobs_add_universe(j, pkg, 0, true);
+
			pkg_jobs_add_universe(j, pkg, 0, true, NULL);
			if(pkg_is_locked(pkg)) {
				/* If a package is locked, then we keep local version */
				pkg_emit_locked(pkg);
@@ -1252,7 +1199,7 @@ jobs_solve_upgrade(struct pkg_jobs *j)
		 */
		struct pkg_job_request *req, *rtmp;
		HASH_ITER(hh, j->request_add, req, rtmp) {
-
			pkg_jobs_add_universe(j, req->pkg, req->priority, true);
+
			pkg_jobs_add_universe(j, req->item->pkg, req->item->priority, true, NULL);
		}
	}

@@ -1261,8 +1208,6 @@ jobs_solve_upgrade(struct pkg_jobs *j)
		return (EPKG_FATAL);
	}

-
	pkg_jobs_update_request_priorities(j);
-

order:

	j->solved ++;
@@ -1294,7 +1239,7 @@ jobs_solve_install(struct pkg_jobs *j)

			pkg = NULL;
			while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) {
-
				pkg_jobs_add_universe(j, pkg, 0, j->flags & PKG_FLAG_RECURSIVE);
+
				pkg_jobs_add_universe(j, pkg, 0, j->flags & PKG_FLAG_RECURSIVE, NULL);

				if (pkg_is_locked(pkg)) {
					/* Keep locked packages to the local version */
@@ -1321,7 +1266,7 @@ jobs_solve_install(struct pkg_jobs *j)
		 */
		struct pkg_job_request *req, *rtmp;
		HASH_ITER(hh, j->request_add, req, rtmp) {
-
			pkg_jobs_add_universe(j, req->pkg, req->priority, true);
+
			pkg_jobs_add_universe(j, req->item->pkg, req->item->priority, true, NULL);
		}
	}

@@ -1330,8 +1275,6 @@ jobs_solve_install(struct pkg_jobs *j)
		return (EPKG_FATAL);
	}

-
	pkg_jobs_update_request_priorities(j);
-

order:

	j->solved ++;
@@ -1385,7 +1328,7 @@ jobs_solve_fetch(struct pkg_jobs *j)
static int
pkg_jobs_sort_priority(struct pkg_solved *r1, struct pkg_solved *r2)
{
-
	return (r2->priority - r1->priority);
+
	return (r2->items[0]->priority - r1->items[0]->priority);
}

int
@@ -1514,8 +1457,8 @@ pkg_jobs_handle_install(struct pkg_solved *ps, struct pkg_jobs *j, bool handle_r
	int flags = 0;
	int retcode = EPKG_FATAL;

-
	old = ps->pkg[1];
-
	new = ps->pkg[0];
+
	old = ps->items[1]->pkg;
+
	new = ps->items[0]->pkg;

	pkg_get(new, PKG_ORIGIN, &pkgorigin,
				PKG_AUTOMATIC, &automatic);
@@ -1612,7 +1555,7 @@ pkg_jobs_execute(struct pkg_jobs *j)
		switch (ps->type) {
		case PKG_SOLVED_DELETE:
		case PKG_SOLVED_UPGRADE_REMOVE:
-
			p = ps->pkg[0];
+
			p = ps->items[0]->pkg;
			pkg_get(p, PKG_NAME, &name);
			if ((strcmp(name, "pkg") == 0 ||
				strcmp(name, "pkg-devel") == 0) && flags != PKG_DELETE_FORCE) {
@@ -1748,7 +1691,7 @@ pkg_jobs_apply(struct pkg_jobs *j)
#define PKG_JOBS_FETCH_CALCULATE(list) do {										\
	DL_FOREACH((list), ps) {														\
		if (ps->type != PKG_SOLVED_DELETE && ps->type != PKG_SOLVED_UPGRADE_REMOVE) {\
-
			p = ps->pkg[0];															\
+
			p = ps->items[0]->pkg;													\
			int64_t pkgsize;														\
			pkg_get(p, PKG_PKGSIZE, &pkgsize, PKG_REPOPATH, &repopath);				\
			snprintf(cachedpath, sizeof(cachedpath), "%s/%s", cachedir, repopath);	\
@@ -1763,7 +1706,7 @@ pkg_jobs_apply(struct pkg_jobs *j)
#define PKG_JOBS_DO_FETCH(list) do {												\
	DL_FOREACH((list), ps) {														\
		if (ps->type != PKG_SOLVED_DELETE && ps->type != PKG_SOLVED_UPGRADE_REMOVE) {\
-
			p = ps->pkg[0];															\
+
			p = ps->items[0]->pkg;													\
			if (pkg_repo_fetch(p) != EPKG_OK)										\
				return (EPKG_FATAL);												\
		}																			\
@@ -1846,7 +1789,7 @@ pkg_jobs_check_conflicts(struct pkg_jobs *j)
			continue;
		}
		else {
-
			p = ps->pkg[0];
+
			p = ps->items[0]->pkg;
			const char *pkgrepopath;
			pkg_get(p, PKG_REPOPATH, &pkgrepopath);
			snprintf(path, sizeof(path), "%s/%s", cachedir,
modified libpkg/pkg_solve.c
@@ -44,7 +44,7 @@
struct pkg_solve_item;

struct pkg_solve_variable {
-
	struct pkg *pkg;
+
	struct pkg_job_universe_item *unit;
	bool to_install;
	bool guess;
	int priority;
@@ -194,7 +194,7 @@ pkg_solve_propagate_pure(struct pkg_solve_problem *problem)
	HASH_ITER(hd, problem->variables_by_digest, var, tvar) {
		if (var->nrules == 0) {
			/* This variable is independent and should not change its state */
-
			var->to_install = (var->pkg->type == PKG_INSTALLED);
+
			var->to_install = (var->unit->pkg->type == PKG_INSTALLED);
			var->resolved = true;
			pkg_debug(2, "leave %s-%s(%d) to %s",
					var->origin, var->digest,
@@ -277,7 +277,7 @@ pkg_solve_sat_problem(struct pkg_solve_problem *problem)
	HASH_ITER(hd, problem->variables_by_digest, var, tvar) {
		if (!var->resolved) {
			/* Guess true for installed packages and false otherwise */
-
			var->guess = (var->pkg->type == PKG_INSTALLED) ? true : false;
+
			var->guess = (var->unit->pkg->type == PKG_INSTALLED) ? true : false;
		}
	}

@@ -348,7 +348,7 @@ pkg_solve_rule_new(void)
}

static struct pkg_solve_variable *
-
pkg_solve_variable_new(struct pkg *pkg, int priority)
+
pkg_solve_variable_new(struct pkg_job_universe_item *item)
{
	struct pkg_solve_variable *result;
	const char *digest, *origin;
@@ -360,9 +360,8 @@ pkg_solve_variable_new(struct pkg *pkg, int priority)
		return (NULL);
	}

-
	result->pkg = pkg;
-
	result->priority = priority;
-
	pkg_get(pkg, PKG_ORIGIN, &origin, PKG_DIGEST, &digest);
+
	result->unit = item;
+
	pkg_get(item->pkg, PKG_ORIGIN, &origin, PKG_DIGEST, &digest);
	/* XXX: Is it safe to save a ptr here ? */
	result->digest = digest;
	result->origin = origin;
@@ -416,7 +415,7 @@ pkg_solve_add_universe_variable(struct pkg_jobs *j,
		return (EPKG_FATAL);
	}
	/* Need to add a variable */
-
	nvar = pkg_solve_variable_new(unit->pkg, unit->priority);
+
	nvar = pkg_solve_variable_new(unit);
	if (nvar == NULL)
		return (EPKG_FATAL);

@@ -430,7 +429,7 @@ pkg_solve_add_universe_variable(struct pkg_jobs *j,
		HASH_FIND(hd, problem->variables_by_digest, digest, strlen(digest), found);
		if (found == NULL) {
			/* Add all alternatives as independent variables */
-
			tvar = pkg_solve_variable_new(unit->pkg, unit->priority);
+
			tvar = pkg_solve_variable_new(unit);
			if (tvar == NULL)
				return (EPKG_FATAL);
			DL_APPEND(nvar, tvar);
@@ -494,7 +493,7 @@ pkg_solve_add_pkg_rule(struct pkg_jobs *j, struct pkg_solve_problem *problem,

	/* Go through all deps in all variables*/
	LL_FOREACH(pvar, cur_var) {
-
		pkg = cur_var->pkg;
+
		pkg = cur_var->unit->pkg;
		HASH_ITER(hh, pkg->deps, dep, dtmp) {
			rule = NULL;
			it = NULL;
@@ -551,7 +550,7 @@ pkg_solve_add_pkg_rule(struct pkg_jobs *j, struct pkg_solve_problem *problem,
			pkg_get(pkg, PKG_ORIGIN, &origin);
			/* Add conflict rule from each of the alternative */
			LL_FOREACH(var, tvar) {
-
				HASH_FIND_STR(tvar->pkg->conflicts, origin, cfound);
+
				HASH_FIND_STR(tvar->unit->pkg->conflicts, origin, cfound);
				if (cfound == NULL) {
					/* Skip non-mutual conflicts */
					continue;
@@ -660,7 +659,7 @@ pkg_solve_jobs_to_sat(struct pkg_jobs *j)
		it = NULL;
		var = NULL;

-
		var = pkg_solve_variable_new(jreq->pkg, jreq->priority);
+
		var = pkg_solve_variable_new(jreq->item);
		if (var == NULL)
			goto err;

@@ -696,7 +695,7 @@ pkg_solve_jobs_to_sat(struct pkg_jobs *j)
		it = NULL;
		var = NULL;

-
		var = pkg_solve_variable_new(jreq->pkg, jreq->priority);
+
		var = pkg_solve_variable_new(jreq->item);
		if (var == NULL)
			goto err;

@@ -738,7 +737,7 @@ pkg_solve_jobs_to_sat(struct pkg_jobs *j)
			HASH_FIND(hd, problem->variables_by_digest, digest, strlen(digest), var);
			if (var == NULL) {
				/* Add new variable */
-
				var = pkg_solve_variable_new(ucur->pkg, ucur->priority);
+
				var = pkg_solve_variable_new(ucur);
				if (var == NULL)
					goto err;
				HASH_ADD_KEYPTR(hd, problem->variables_by_digest,
@@ -824,11 +823,11 @@ pkg_solve_insert_res_job (struct pkg_solve_variable *var,
	int seen_add = 0, seen_del = 0;

	LL_FOREACH(var, cur_var) {
-
		if (cur_var->to_install && cur_var->pkg->type != PKG_INSTALLED) {
+
		if (cur_var->to_install && cur_var->unit->pkg->type != PKG_INSTALLED) {
			add_var = cur_var;
			seen_add ++;
		}
-
		else if (!cur_var->to_install && cur_var->pkg->type == PKG_INSTALLED) {
+
		else if (!cur_var->to_install && cur_var->unit->pkg->type == PKG_INSTALLED) {
			del_var = cur_var;
			seen_del ++;
		}
@@ -845,46 +844,26 @@ pkg_solve_insert_res_job (struct pkg_solve_variable *var,
			return;
		}
		if (seen_add == 0 && seen_del != 0) {
-
			res->priority = del_var->priority;
-
			res->pkg[0] = del_var->pkg;
+
			res->items[0] = del_var->unit;
			res->type = PKG_SOLVED_DELETE;
			DL_APPEND(j->jobs, res);
-
			pkg_debug(3, "pkg_solve: schedule deletion of %s(%d) %s",
-
					del_var->origin, res->priority, del_var->digest);
+
			pkg_debug(3, "pkg_solve: schedule deletion of %s %s",
+
					del_var->origin, del_var->digest);
		}
		else if (seen_del == 0 && seen_add != 0) {
-
			res->priority = add_var->priority;
-
			res->pkg[0] = add_var->pkg;
+
			res->items[0] = add_var->unit;
			res->type = PKG_SOLVED_INSTALL;
			DL_APPEND(j->jobs, res);
-
			pkg_debug(3, "pkg_solve: schedule installation of %s(%d) %s",
-
					add_var->origin, res->priority, add_var->digest);
+
			pkg_debug(3, "pkg_solve: schedule installation of %s %s",
+
					add_var->origin, add_var->digest);
		}
		else {
-
			assert(del_var->priority >= add_var->priority);
-
			if (del_var->priority > add_var->priority) {
-
				dres = calloc(1, sizeof(struct pkg_solved));
-
				if (dres == NULL) {
-
					pkg_emit_errno("calloc", "pkg_solved");
-
					return;
-
				}
-
				dres->priority = del_var->priority;
-
				dres->pkg[0] = del_var->pkg;
-
				dres->pkg[1] = add_var->pkg;
-
				dres->type = PKG_SOLVED_UPGRADE_REMOVE;
-
				DL_APPEND(j->jobs, dres);
-
				res->already_deleted = true;
-
				j->count ++;
-
			}
-
			res->priority = add_var->priority;
-
			res->pkg[0] = add_var->pkg;
-
			res->pkg[1] = del_var->pkg;
+
			res->items[0] = add_var->unit;
+
			res->items[1] = del_var->unit;
			res->type = PKG_SOLVED_UPGRADE;
			DL_APPEND(j->jobs, res);
-
			pkg_debug(3, "pkg_solve: schedule upgrade(%s) of %s(%d->%d) from %s to %s",
-
					res->already_deleted ? "delayed" : "immediate",
-
					del_var->origin, del_var->priority,
-
					add_var->priority, del_var->digest, add_var->digest);
+
			pkg_debug(3, "pkg_solve: schedule upgrade of %s from %s to %s",
+
					del_var->origin, del_var->digest, add_var->digest);
		}
		j->count ++;
	}
modified libpkg/private/pkg.h
@@ -196,28 +196,26 @@ struct pkg_option {
	UT_hash_handle	hh;
};

-
struct pkg_job_request {
+
struct pkg_job_universe_item {
	struct pkg *pkg;
+
	UT_hash_handle hh;
	int priority;
+
	struct pkg_job_universe_item *next, *prev;
+
};
+

+
struct pkg_job_request {
+
	struct pkg_job_universe_item *item;
	bool skip;
	UT_hash_handle hh;
};

struct pkg_solved {
-
	struct pkg *pkg[2];
-
	int priority;
+
	struct pkg_job_universe_item *items[2];
	pkg_solved_t type;
	bool already_deleted;
	struct pkg_solved *prev, *next;
};

-
struct pkg_job_universe_item {
-
	struct pkg *pkg;
-
	UT_hash_handle hh;
-
	int priority;
-
	struct pkg_job_universe_item *next, *prev;
-
};
-

struct pkg_job_seen {
	struct pkg_job_universe_item *un;
	const char *digest;