Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
schedule: convert to vector
Baptiste Daroussin committed 1 year ago
commit fef3ef213fc3828b173fb0acd8be526cd1290cd8
parent dfef457
6 files changed +85 -71
modified libpkg/pkg_cudf.c
@@ -350,7 +350,7 @@ pkg_jobs_cudf_insert_res_job (pkg_solved_list *target,
	if (it_old != NULL)
		res->items[1] = it_old;

-
	tll_push_back(*target, res);
+
	vec_push(target, res);
}

struct pkg_cudf_entry {
modified libpkg/pkg_jobs.c
@@ -67,7 +67,6 @@
#include "private/pkg.h"
#include "private/pkgdb.h"
#include "private/pkg_jobs.h"
-
#include "tllist.h"

extern struct pkg_ctx ctx;

@@ -205,7 +204,7 @@ pkg_jobs_free(struct pkg_jobs *j)
	j->request_delete = NULL;

	pkg_jobs_universe_free(j->universe);
-
	tll_free_and_free(j->jobs, free);
+
	vec_free_and_free(&j->jobs, free);
	LL_FREE(j->patterns, pkg_jobs_pattern_free);
	if (j->triggers.cleanup != NULL) {
		vec_free_and_free(j->triggers.cleanup, trigger_free);
@@ -307,26 +306,28 @@ pkg_jobs_iter(struct pkg_jobs *j, void **iter,
{
	struct pkg_solved *s;
	struct {
-
		typeof(*(j->jobs.head)) *it;
+
		pkg_solved_list *list;
+
		size_t pos;
	} *t;
	t = *iter;
	if (*iter == NULL) {
		t = xcalloc(1, sizeof(*t));
		*iter = t;
-
	} else if (t->it == NULL) {
+
	} else if (t->pos >= t->list->len) {
			free(t);
			return (false);
	}

-
	if (tll_length(j->jobs) == 0)
+
	if (j->jobs.len == 0)
		return (false);
-
	if (t->it == NULL)
-
		t->it = j->jobs.head;
-
	s = t->it->item;
+
	if (t->list == NULL) {
+
		t->list = &j->jobs;
+
		t->pos = 0;
+
	}
+
	s = t->list->d[t->pos++];
	*new = s->items[0]->pkg;
	*old = s->items[1] ? s->items[1]->pkg : NULL;
	*type = s->type;
-
	t->it = t->it->next;
	return (true);
}

@@ -1363,8 +1364,8 @@ pkg_jobs_set_deinstall_reasons(struct pkg_jobs *j)
	struct pkg_job_request *jreq;
	struct pkg *req_pkg, *pkg;

-
	tll_foreach(j->jobs, it) {
-
		sit = it->item;
+
	vec_foreach(j->jobs, i) {
+
		sit = j->jobs.d[i];
		jreq = pkg_jobs_find_deinstall_request(sit->items[0], j, 0);
		if (jreq != NULL && jreq->item->unit != sit->items[0]) {
			req_pkg = jreq->item->pkg;
@@ -1900,10 +1901,10 @@ pkg_jobs_solve(struct pkg_jobs *j)
	 * conflicts if we can check for and solve conflicts without first
	 * needing to fetch.
	 */
-
	tll_foreach(j->jobs, job) {
+
	vec_foreach(j->jobs, i) {
		struct pkg *p;

-
		p = ((struct pkg_solved *)job->item)->items[0]->pkg;
+
		p = ((struct pkg_solved *)j->jobs.d[i])->items[0]->pkg;
		if (p->type != PKG_REMOTE)
			continue;

@@ -1922,7 +1923,7 @@ pkg_jobs_solve(struct pkg_jobs *j)
			rc = pkg_jobs_check_conflicts(j);
			if (rc == EPKG_CONFLICT) {
				/* Cleanup results */
-
				tll_free_and_free(j->jobs, free);
+
				vec_free_and_free(&j->jobs, free);
				has_conflicts = true;
				pkg_jobs_solve(j);
			}
@@ -1940,7 +1941,7 @@ pkg_jobs_count(struct pkg_jobs *j)
{
	assert(j != NULL);

-
	return (tll_length(j->jobs));
+
	return (j->jobs.len);
}

int
@@ -2086,9 +2087,9 @@ pkg_jobs_execute(struct pkg_jobs *j)
	if (retcode != EPKG_OK)
		return (retcode);

-
	total_actions = tll_length(j->jobs);
-
	tll_foreach(j->jobs, _p) {
-
		struct pkg_solved *ps = _p->item;
+
	total_actions = j->jobs.len;
+
	vec_foreach(j->jobs, i) {
+
		struct pkg_solved *ps = j->jobs.d[i];

		pkg_emit_new_action(++current_action, total_actions);
		switch (ps->type) {
@@ -2180,7 +2181,7 @@ pkg_jobs_apply(struct pkg_jobs *j)
						rc = pkg_jobs_check_conflicts(j);
						if (rc == EPKG_CONFLICT) {
							/* Cleanup results */
-
							tll_free_and_free(j->jobs, free);
+
							vec_free_and_free(&j->jobs, free);
							has_conflicts = true;
							rc = pkg_jobs_solve(j);
						}
@@ -2241,8 +2242,8 @@ pkg_jobs_fetch(struct pkg_jobs *j)
		cachedir = j->destdir;

	/* check for available size to fetch */
-
	tll_foreach(j->jobs, _p) {
-
		struct pkg_solved *ps = _p->item;
+
	vec_foreach(j->jobs, i) {
+
		struct pkg_solved *ps = j->jobs.d[i];
		if (ps->type != PKG_SOLVED_DELETE && ps->type != PKG_SOLVED_UPGRADE_REMOVE) {
			p = ps->items[0]->pkg;
			if (p->type != PKG_REMOTE)
@@ -2307,8 +2308,8 @@ pkg_jobs_fetch(struct pkg_jobs *j)
		return (EPKG_OK); /* don't download anything */

	/* Fetch */
-
	tll_foreach(j->jobs, _p) {
-
		struct pkg_solved *ps = _p->item;
+
	vec_foreach(j->jobs, i) {
+
		struct pkg_solved *ps = j->jobs.d[i];
		if (ps->type != PKG_SOLVED_DELETE && ps->type != PKG_SOLVED_UPGRADE_REMOVE) {
			p = ps->items[0]->pkg;
			if (p->type != PKG_REMOTE)
@@ -2339,8 +2340,8 @@ pkg_jobs_check_conflicts(struct pkg_jobs *j)
	pkg_emit_integritycheck_begin();
	j->conflicts_registered = 0;

-
	tll_foreach(j->jobs, _p) {
-
		struct pkg_solved *ps = _p->item;
+
	vec_foreach(j->jobs, i) {
+
		struct pkg_solved *ps = j->jobs.d[i];
		if (ps->type == PKG_SOLVED_DELETE || ps->type == PKG_SOLVED_UPGRADE_REMOVE) {
			continue;
		}
modified libpkg/pkg_jobs_schedule.c
@@ -200,8 +200,10 @@ pkg_jobs_schedule_dbg_job(pkg_solved_list *jobs, struct pkg_solved *job)
	    job->items[0]->pkg->uid);

	debug_edges = true;
-
	tll_foreach(*jobs, it) {
-
		pkg_jobs_schedule_graph_edge(job, it->item);
+
	vec_foreach(*jobs, i) {
+
		if (jobs->d[i] == NULL)
+
			continue;
+
		pkg_jobs_schedule_graph_edge(job, jobs->d[i]);
	}
	debug_edges = false;
}
@@ -210,8 +212,10 @@ static bool
pkg_jobs_schedule_has_incoming_edge(pkg_solved_list *nodes,
    struct pkg_solved *node)
{
-
	tll_foreach(*nodes, it) {
-
		if (pkg_jobs_schedule_graph_edge(it->item, node)) {
+
	vec_foreach(*nodes, i) {
+
		if (nodes->d[i] == NULL)
+
			continue;
+
		if (pkg_jobs_schedule_graph_edge(nodes->d[i], node)) {
			return (true);
		}
	}
@@ -238,8 +242,11 @@ pkg_jobs_schedule_priority(struct pkg_solved *node)

/* This comparison function is used as a tiebreaker in the topological sort. */
static int
-
pkg_jobs_schedule_cmp_available(struct pkg_solved *a, struct pkg_solved *b)
+
pkg_jobs_schedule_cmp_available(const void *va, const void *vb)
{
+
	struct pkg_solved *a = *(struct pkg_solved **)va;
+
	struct pkg_solved *b = *(struct pkg_solved **)vb;
+

	int ret = pkg_jobs_schedule_priority(b) - pkg_jobs_schedule_priority(a);
	if (ret == 0) {
		/* Falling back to lexicographical ordering ensures that job execution
@@ -254,34 +261,39 @@ pkg_jobs_schedule_cmp_available(struct pkg_solved *a, struct pkg_solved *b)
static void
pkg_jobs_schedule_topological_sort(pkg_solved_list *jobs)
{
-
	pkg_solved_list sorted = tll_init();
-
	pkg_solved_list available = tll_init();
+
	pkg_solved_list sorted = vec_init();
+
	pkg_solved_list available = vec_init();
+
	size_t left = jobs->len;

	/* Place all job nodes with no incoming edges in available */
-
	tll_foreach(*jobs, it) {
-
		if (!pkg_jobs_schedule_has_incoming_edge(jobs, it->item) &&
-
		    !pkg_jobs_schedule_has_incoming_edge(&available, it->item)) {
-
			tll_push_front(available, it->item);
-
			tll_remove(*jobs, it);
+
	vec_foreach(*jobs, i) {
+
		if (!pkg_jobs_schedule_has_incoming_edge(jobs, jobs->d[i]) &&
+
		    !pkg_jobs_schedule_has_incoming_edge(&available, jobs->d[i])) {
+
			vec_push(&available, jobs->d[i]);
+
			jobs->d[i] = NULL;
+
			left--;
		}
	}

-
	while (tll_length(available) > 0) {
+
	while (available.len > 0) {
		/* Add the highest priority job from the set of available jobs
		 * to the sorted list */
-
		tll_sort(available, pkg_jobs_schedule_cmp_available);
-
		struct pkg_solved *node = tll_pop_front(available);
-
		tll_push_back(sorted, node);
+
		qsort(available.d, available.len, sizeof(available.d[0]), pkg_jobs_schedule_cmp_available);
+
		struct pkg_solved *node = vec_pop(&available);
+
		vec_push(&sorted, node);

		/* Again, place all job nodes with no incoming edges in the set
		 * of available jobs, ignoring any incoming edges from job nodes
		 * already added to the sorted list */
-
		tll_foreach(*jobs, it) {
-
			if (pkg_jobs_schedule_graph_edge(node, it->item)) {
-
				if (!pkg_jobs_schedule_has_incoming_edge(jobs, it->item) &&
-
				    !pkg_jobs_schedule_has_incoming_edge(&available, it->item)) {
-
					tll_push_front(available, it->item);
-
					tll_remove(*jobs, it);
+
		vec_foreach(*jobs, i) {
+
			if (jobs->d[i] == NULL)
+
				continue;
+
			if (pkg_jobs_schedule_graph_edge(node, jobs->d[i])) {
+
				if (!pkg_jobs_schedule_has_incoming_edge(jobs, jobs->d[i]) &&
+
				    !pkg_jobs_schedule_has_incoming_edge(&available, jobs->d[i])) {
+
					vec_push(&available, jobs->d[i]);
+
					jobs->d[i] = NULL;
+
					left--;
				}
			}
		}
@@ -290,9 +302,10 @@ pkg_jobs_schedule_topological_sort(pkg_solved_list *jobs)
	/* The jobs list will only be non-empty at this point if there is a
	 * cycle in the graph and all cycles must be eliminated by splitting
	 * upgrade jobs before calling this function. */
-
	assert(tll_length(*jobs) == 0);
+
	assert(left == 0);

-
	*jobs = sorted;
+
	free(jobs->d);
+
	jobs->d = sorted.d;
}

/*
@@ -311,12 +324,12 @@ pkg_jobs_schedule_find_cycle(pkg_solved_list *jobs,
	node->path_next = *path;
	*path = node;

-
	tll_foreach(*jobs, it) {
-
		if (pkg_jobs_schedule_graph_edge(node, it->item)) {
-
			switch (it->item->mark){
+
	vec_foreach(*jobs, i) {
+
		if (pkg_jobs_schedule_graph_edge(node, jobs->d[i])) {
+
			switch (jobs->d[i]->mark){
			case PKG_SOLVED_CYCLE_MARK_NONE:;
				struct pkg_solved *cycle =
-
				    pkg_jobs_schedule_find_cycle(jobs, path, it->item);
+
				    pkg_jobs_schedule_find_cycle(jobs, path, jobs->d[i]);
				if (cycle != NULL) {
					return (cycle);
				}
@@ -324,7 +337,7 @@ pkg_jobs_schedule_find_cycle(pkg_solved_list *jobs,
			case PKG_SOLVED_CYCLE_MARK_DONE:
				break;
			case PKG_SOLVED_CYCLE_MARK_PATH:
-
				return (it->item); /* Found a cycle */
+
				return (jobs->d[i]); /* Found a cycle */
			default:
				assert(false);
			}
@@ -345,21 +358,21 @@ int pkg_jobs_schedule(struct pkg_jobs *j)
	while (true) {
		dbg(3, "checking job scheduling graph for cycles...");

-
		tll_foreach(j->jobs, it) {
-
			it->item->mark = PKG_SOLVED_CYCLE_MARK_NONE;
-
			it->item->path_next = NULL;
+
		vec_foreach(j->jobs, i) {
+
			j->jobs.d[i]->mark = PKG_SOLVED_CYCLE_MARK_NONE;
+
			j->jobs.d[i]->path_next = NULL;

-
			pkg_jobs_schedule_dbg_job(&j->jobs, it->item);
+
			pkg_jobs_schedule_dbg_job(&j->jobs, j->jobs.d[i]);
		}

		/* The graph may not be connected, in which case it is necessary to
		 * run multiple searches for cycles from different start nodes. */
		struct pkg_solved *path = NULL;
		struct pkg_solved *cycle = NULL;
-
		tll_foreach(j->jobs, it) {
-
			switch (it->item->mark) {
+
		vec_foreach(j->jobs, i) {
+
			switch (j->jobs.d[i]->mark) {
			case PKG_SOLVED_CYCLE_MARK_NONE:
-
				cycle = pkg_jobs_schedule_find_cycle(&j->jobs, &path, it->item);
+
				cycle = pkg_jobs_schedule_find_cycle(&j->jobs, &path, j->jobs.d[i]);
				break;
			case PKG_SOLVED_CYCLE_MARK_DONE:
				break;
@@ -409,7 +422,7 @@ int pkg_jobs_schedule(struct pkg_jobs *j)
		path->type = PKG_SOLVED_UPGRADE_INSTALL;
		path->items[1] = NULL;
		path->xlink = new;
-
		tll_push_back(j->jobs, new);
+
		vec_push(&j->jobs, new);
	}

	pkg_jobs_schedule_topological_sort(&j->jobs);
modified libpkg/pkg_solve.c
@@ -1333,7 +1333,7 @@ pkg_solve_insert_res_job (struct pkg_solve_variable *var,
				res->items[0] = add_var->unit;
				res->type = (j->type == PKG_JOBS_FETCH) ?
								PKG_SOLVED_FETCH : PKG_SOLVED_INSTALL;
-
				tll_push_back(j->jobs, res);
+
				vec_push(&j->jobs, res);
				dbg(3, "pkg_solve: schedule installation of %s %s",
					add_var->uid, add_var->digest);
			}
@@ -1342,7 +1342,7 @@ pkg_solve_insert_res_job (struct pkg_solve_variable *var,
				res->items[0] = add_var->unit;
				res->items[1] = del_var->unit;
				res->type = PKG_SOLVED_UPGRADE;
-
				tll_push_back(j->jobs, res);
+
				vec_push(&j->jobs, res);
				dbg(3, "pkg_solve: schedule upgrade of %s from %s to %s",
					del_var->uid, del_var->digest, add_var->digest);
			}
@@ -1362,7 +1362,7 @@ pkg_solve_insert_res_job (struct pkg_solve_variable *var,
				res = xcalloc(1, sizeof(struct pkg_solved));
				res->items[0] = cur_var->unit;
				res->type = PKG_SOLVED_DELETE;
-
				tll_push_back(j->jobs, res);
+
				vec_push(&j->jobs, res);
				dbg(3, "schedule deletion of %s %s",
					cur_var->uid, cur_var->digest);
			}
modified libpkg/private/pkg_jobs.h
@@ -97,7 +97,7 @@ struct pkg_solved {
	enum pkg_solved_cycle_mark mark;/* scheduling cycle detection */
	struct pkg_solved *path_next;	/* scheduling cycle detection */
};
-
typedef tll(struct pkg_solved *) pkg_solved_list;
+
typedef vec_t(struct pkg_solved *) pkg_solved_list;

struct pkg_job_provide {
	struct pkg_job_universe_item *un;
modified tests/frontend/conflicts.sh
@@ -353,14 +353,14 @@ Installed packages to be REMOVED:
Number of packages to be removed: 2
Number of packages to be installed: 2
Number of packages to be upgraded: 1
-
[1/6] Deinstalling other-1.0...
-
[2/6] Deinstalling foo-1.0...
+
[1/6] Deinstalling foo-1.0...
+
[2/6] Deinstalling other-1.0...
[3/6] Deinstalling bar-1.0...
[3/6] Deleting files for bar-1.0:  done
[4/6] Installing bar1-1.1...
[4/6] Extracting bar1-1.1:  done
-
[5/6] Installing foo-1.0_1...
-
[6/6] Installing arp-1.0_1...
+
[5/6] Installing arp-1.0_1...
+
[6/6] Installing foo-1.0_1...
"

	atf_check \