Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Continue to rework adding requests.
Vsevolod Stakhov committed 11 years ago
commit 451d0f8179c20a605e3d314ff52595a87c8cde90
parent bde55bf
3 files changed +217 -11
modified libpkg/pkg_jobs.c
@@ -43,6 +43,8 @@
#include <sys/wait.h>
#include <ctype.h>

+
#include "utarray.h"
+

#include "pkg.h"
#include "private/event.h"
#include "private/pkg.h"
@@ -250,6 +252,41 @@ pkg_jobs_iter(struct pkg_jobs *jobs, void **iter,
}

static struct pkg_job_request_item*
+
pkg_jobs_add_req_from_universe(struct pkg_job_request *head,
+
	struct pkg_job_universe_item *un)
+
{
+
	struct pkg_job_request *req;
+
	struct pkg_job_request_item *nit;
+
	const char *uid;
+
	struct pkg_job_universe_item *uit;
+

+
	pkg_get(un->pkg, PKG_UNIQUEID, &uid);
+
	HASH_FIND_STR(head, uid, req);
+

+
	if (req == NULL) {
+
		req = calloc(1, sizeof(*req));
+
		if (req == NULL) {
+
			pkg_emit_errno("malloc", "struct pkg_job_request");
+
			return (NULL);
+
		}
+
		HASH_ADD_KEYPTR(hh, *head, uid, strlen(uid), req);
+
	}
+

+
	DL_FOREACH(un, uit) {
+
		nit = calloc(1, sizeof(*nit));
+
		if (nit == NULL) {
+
			pkg_emit_errno("malloc", "struct pkg_job_request_item");
+
			return (NULL);
+
		}
+
		nit->pkg = uit->pkg;
+
		nit->unit = uit;
+
		DL_APPEND(req->item, nit);
+
	}
+

+
	return (req->item);
+
}
+

+
static struct pkg_job_request_item*
pkg_jobs_add_req(struct pkg_jobs *j, struct pkg *pkg)
{
	struct pkg_job_request *req, *head;
@@ -260,6 +297,14 @@ pkg_jobs_add_req(struct pkg_jobs *j, struct pkg *pkg)

	assert(pkg != NULL);

+
	if (!IS_DELETE(j)) {
+
		head = &j->request_add;
+
		assert(pkg->type != PKG_INSTALLED);
+
	}
+
	else {
+
		head = &j->request_delete;
+
		assert(pkg->type == PKG_INSTALLED);
+
	}
	rc = pkg_jobs_universe_add_pkg(j->universe, pkg, false, &un);
	if (rc == EPKG_END) {
		/*
@@ -268,9 +313,17 @@ pkg_jobs_add_req(struct pkg_jobs *j, struct pkg *pkg)
		 * we thus won't do anything with this item, as it is definitely useless
		 */
		HASH_FIND_STR(*head, uid, req);
-
		DL_FOREACH(req->item, nit) {
-
			if (nit->unit == un)
-
				return (nit);
+
		if (req != NULL) {
+
			DL_FOREACH(req->item, nit) {
+
				if (nit->unit == un)
+
					return (nit);
+
			}
+
		}
+
		else {
+
			/*
+
			 * We need to add request chain from the universe chain
+
			 */
+
			return (pkg_jobs_add_req_from_universe(head, un));
		}

		return (NULL);
@@ -281,14 +334,6 @@ pkg_jobs_add_req(struct pkg_jobs *j, struct pkg *pkg)
		 */
		return (NULL);
	}
-
	if (!IS_DELETE(j)) {
-
		head = &j->request_add;
-
		assert(pkg->type != PKG_INSTALLED);
-
	}
-
	else {
-
		head = &j->request_delete;
-
		assert(pkg->type == PKG_INSTALLED);
-
	}

	pkg_get(pkg, PKG_UNIQUEID, &uid);
	HASH_FIND_STR(*head, uid, req);
@@ -317,6 +362,79 @@ pkg_jobs_add_req(struct pkg_jobs *j, struct pkg *pkg)
	return (nit);
}

+
/*
+
 * Post-process add request and handle flags:
+
 * upgrade - search for upgrades for dependencies and add them to the request
+
 * force - all upgrades are forced
+
 * reverse - try to upgrade reverse deps as well
+
 */
+
static void
+
pkg_jobs_process_add_request(struct pkg_jobs *j, bool top)
+
{
+
	bool force = j->flags & PKG_FLAG_FORCE,
+
		 reverse = j->flags & PKG_FLAG_RECURSIVE,
+
		 upgrade = j->type == PKG_UPGRADE;
+
	struct pkg_job_request *req, *tmp, *found;
+
	struct pkg_job_request_item *it;
+
	struct pkg_job_universe_item *un;
+
	struct pkg_dep *d;
+
	struct pkg *lp;
+
	int (*deps_func)(const struct pkg *pkg, struct pkg_dep **d);
+
	UT_array *to_process = NULL;
+
	const char *seen;
+

+
	if (upgrade || reverse) {
+
		utarray_new(to_process, &ut_ptr_icd);
+

+
		HASH_ITER(hh, j->request_add, req, tmp) {
+
			DL_FOREACH(req, it) {
+
				if (reverse)
+
					deps_func = pkg_rdeps;
+
				else
+
					deps_func = pkg_deps;
+

+
				d = NULL;
+
				while (deps_func(it->pkg, &d) == EPKG_OK) {
+
					/*
+
					 * Do not add duplicated upgrade candidates
+
					 */
+
					HASH_FIND_STR(j->request_add, d->uid, found);
+
					if (found != NULL)
+
						continue;
+

+
					lp = pkg_jobs_universe_get_local(j->universe,
+
						d->uid, 0);
+
					/*
+
					 * Here we need to check whether specific remote package
+
					 * is newer than a local one
+
					 */
+
					un = pkg_jobs_universe_get_upgrade_candidates(j->universe,
+
						d->uid, lp, force);
+
					utarray_push(to_process, &un);
+
				}
+
			}
+
		}
+
	}
+

+
	if (to_process) {
+
		/* Add all items to the request */
+
		struct pkg_job_universe_item **pun = NULL;
+

+
		if (to_process->n > 0) {
+
			while ((pun = utarray_next(to_process, pun)) != NULL) {
+
				pkg_jobs_add_req_from_universe(j->request_add, *pun);
+
			}
+
			/* Now recursively process all items checked */
+
			pkg_jobs_process_add_request(j, false);
+
		}
+
		utarray_free(to_process);
+
	}
+

+
	if (top) {
+

+
	}
+
}
+

static int
pkg_jobs_set_execute_priority(struct pkg_jobs *j, struct pkg_solved *solved)
{
modified libpkg/pkg_jobs_universe.c
@@ -32,6 +32,8 @@
#include <string.h>
#include <ctype.h>

+
#include "utarray.h"
+

#include "pkg.h"
#include "private/event.h"
#include "private/pkg.h"
@@ -840,3 +842,76 @@ pkg_jobs_universe_process_upgrade_chains(struct pkg_jobs *j)
		}
	}
}
+

+

+
struct pkg_job_universe_item*
+
pkg_jobs_universe_get_upgrade_candidates(struct pkg_jobs_universe *universe,
+
	const char *uid, struct pkg *lp, bool force)
+
{
+
	struct pkg *pkg = NULL, *selected = lp;
+
	struct pkgdb_it *it;
+
	struct pkg_job_universe_item *unit;
+
	int flag = PKG_LOAD_BASIC|PKG_LOAD_DEPS|PKG_LOAD_OPTIONS|
+
					PKG_LOAD_SHLIBS_REQUIRED|PKG_LOAD_SHLIBS_PROVIDED|
+
					PKG_LOAD_ANNOTATIONS|PKG_LOAD_CONFLICTS;
+
	UT_array *candidates;
+
	struct pkg **p = NULL;
+

+
	HASH_FIND(hh, universe->items, uid, strlen(uid), unit);
+
	if (unit != NULL) {
+
		/*
+
		 * If a unit has been found, we have already found the potential
+
		 * upgrade chain for it
+
		 */
+
		return (unit);
+
	}
+

+
	if ((it = pkgdb_repo_query(universe->j->db, uid, MATCH_EXACT,
+
		universe->j->reponame)) == NULL)
+
		return (NULL);
+

+
	utarray_new(candidates, &ut_ptr_icd);
+
	while (pkgdb_it_next(it, &pkg, flag) == EPKG_OK) {
+

+
		if (force) {
+
			/* Just add everything */
+
			selected = pkg;
+
		}
+
		else {
+
			if (selected == lp &&
+
					(lp == NULL || pkg_jobs_need_upgrade(pkg, lp)))
+
				selected = pkg;
+
			else if (pkg_version_change_between(pkg, selected) == PKG_UPGRADE)
+
				selected = pkg;
+
		}
+
		utarray_push_back(candidates, &pkg);
+
		pkg = NULL;
+
	}
+

+
	pkgdb_it_free(it);
+

+
	if (lp != NULL) {
+
		/* Add local package to the universe as well */
+
		pkg_jobs_universe_add_pkg(universe, lp, false, NULL);
+
	}
+
	if (selected != lp) {
+
		/* We need to add the whole chain of upgrade candidates */
+
		while ((p = utarray_next(candidates, p)) != NULL) {
+
			pkg_jobs_universe_add_pkg(universe, *p, false, NULL);
+
		}
+
	}
+
	else {
+
		while ((p = utarray_next(candidates, p)) != NULL) {
+
			pkg_free(*p);
+
		}
+

+
		utarray_free(candidates);
+

+
		return (NULL);
+
	}
+

+
	HASH_FIND(hh, universe->items, uid, strlen(uid), unit);
+
	utarray_free(candidates);
+

+
	return (unit);
+
}
modified libpkg/private/pkg_jobs.h
@@ -227,4 +227,17 @@ bool pkg_jobs_need_upgrade(struct pkg *rp, struct pkg *lp);
 */
void pkg_jobs_universe_process_upgrade_chains(struct pkg_jobs *j);

+
/*
+
 * Find upgrade candidates for a specified local package `lp`
+
 * This function updates universe as following:
+
 * - if `lp` is not null it is always added to the universe
+
 * - if `uid` is in the universe, then the existing upgrade chain is returned
+
 * - if `force` is true then all candidates are added to the universe
+
 * - if `forece` is false then *all* candidates are added to the universe, but
+
 * merely if *any* of remote packages is an upgrade for local one
+
 */
+
struct pkg_job_universe_item*
+
pkg_jobs_universe_get_upgrade_candidates(struct pkg_jobs_universe *universe,
+
	const char *uid, struct pkg *lp, bool force);
+

#endif /* PKG_JOBS_H_ */