aboutsummaryrefslogtreecommitdiff
path: root/src/queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/queue.c')
-rw-r--r--src/queue.c141
1 files changed, 62 insertions, 79 deletions
diff --git a/src/queue.c b/src/queue.c
index 1fb5ae7..b02474e 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -11,8 +11,45 @@
#define MAX_NIX_PKG_COUNT 200000
static int queue_push(struct queue *queue, struct job *job);
-static int queue_htab_job_merge(struct job **job, struct hsearch_data *htab);
-static int queue_htab_parent_merge(struct job *to, struct job *from);
+static int queue_htab_job_merge(struct job **job, struct htab *htab);
+static int queue_dag_isolate(struct job *job, struct job *keep_parent,
+ struct job_clist *jobs, struct htab *htab);
+
+static int queue_dag_isolate(struct job *job, struct job *keep_parent,
+ struct job_clist *jobs, struct htab *htab)
+{
+ int ret;
+
+ for (size_t i = 0; i < job->deps_filled; i++) {
+ ret = queue_dag_isolate(job->deps[i], job, jobs, htab);
+ if (ret < 0)
+ return ret;
+ }
+
+ for (size_t i = 0; i < job->parents_filled; i++) {
+ if (job->parents[i] == keep_parent)
+ continue;
+
+ job_deps_list_rm(job->parents[i], job);
+ }
+
+ if (keep_parent != NULL) {
+ job->parents[0] = keep_parent;
+ job->parents_filled = 1;
+ } else {
+ /* it must be tha parent */
+ job->parents_filled = 0;
+ }
+
+ if (!job->transitive)
+ CIRCLEQ_REMOVE(jobs, job, clist);
+
+ ret = htab_delete(htab, job->drv_path);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
void *queue_thread_entry(void *queue_thread)
{
@@ -41,9 +78,8 @@ void *queue_thread_entry(void *queue_thread)
pthread_exit(NULL);
}
-int queue_pop(struct queue *queue, struct job **job, struct hsearch_data *htab)
+int queue_pop(struct queue *queue, struct job **job, struct htab *htab)
{
- ENTRY e, *ep;
int ret;
struct job *j = CIRCLEQ_FIRST(&queue->jobs);
@@ -54,50 +90,12 @@ int queue_pop(struct queue *queue, struct job **job, struct hsearch_data *htab)
}
pthread_mutex_lock(&queue->mutex);
-
- CIRCLEQ_REMOVE(&queue->jobs, j, clist);
- if (j->parents_filled <= 0) {
- e.key = j->drv_path;
- ret = hsearch_r(e, FIND, &ep, htab);
- if (ret == 0) {
- print_err("%s", strerror(errno));
- }
- else
- ep->data = NULL;
- }
-
- pthread_mutex_unlock(&queue->mutex);
-
- *job = j;
- return 0;
-}
-
-static int queue_htab_parent_merge(struct job *to, struct job *from)
-{
- int ret;
-
- /* the output from nix-eval-jobs("from") can only have maximum one
- * parent */
- for (size_t i = 0; i < to->parents_filled; i++) {
- if (strcmp(to->parents[i]->drv_path,
- from->parents[0]->drv_path))
- continue;
-
- /* steal name from "from" */
- if (to->parents[i]->name == NULL) {
- to->parents[i]->name =
- from->parents[0]->name;
- from->parents[0]->name = NULL;
- }
-
- return 0;
- }
-
- ret = job_parents_list_insert(to, from->parents[0]);
+ ret = queue_dag_isolate(j, NULL, &queue->jobs, htab);
if (ret < 0)
return ret;
- from->parents_filled = 0;
+ pthread_mutex_unlock(&queue->mutex);
+ *job = j;
return 0;
}
@@ -107,26 +105,21 @@ static int queue_htab_parent_merge(struct job *to, struct job *from)
* - only childrens or dependencies have parent node
* - only root node have dependencies
*/
-static int queue_htab_job_merge(struct job **job, struct hsearch_data *htab)
+static int queue_htab_job_merge(struct job **job, struct htab *htab)
{
struct job *jtab;
- ENTRY e, *ep;
+ ENTRY *ep;
int ret;
- e.key = (*job)->drv_path;
- ret = hsearch_r(e, FIND, &ep, htab);
- if (ret == 0) {
- if (errno != ESRCH) {
- print_err("%s", strerror(errno));
- return -errno;
- }
-
- e.data = *job;
- ret = hsearch_r(e, ENTER, &ep, htab);
- if (ret == 0) {
- print_err("%s", strerror(errno));
- return -errno;
- }
+ // e.key = (*job)->drv_path;
+ // ret = hsearch_r(e, FIND, &ep, htab);
+ ret = htab_search(htab, (*job)->drv_path, &ep);
+ if (ret < 0) {
+ return ret;
+ } else if (ret == ESRCH) {
+ ret = htab_enter(htab, (*job)->drv_path, *job);
+ if (ret < 0)
+ return ret;
for (size_t i = 0; i < (*job)->deps_filled; i++) {
ret = queue_htab_job_merge(&(*job)->deps[i], htab);
@@ -148,12 +141,15 @@ static int queue_htab_job_merge(struct job **job, struct hsearch_data *htab)
/* only recursive calls with childrens or dependencies can enter this
* for a recursive call to happen the parent was just entered into htab
- * so, update the parent's deps reference to point to the node in htab
+ * so,
+ * - update parent's reference to point to jtab (done by *job = jtab)
+ * - insert the parent to jtab
*/
if ((*job)->parents_filled > 0) {
- ret = queue_htab_parent_merge(jtab, *job);
+ ret = job_parents_list_insert(jtab, (*job)->parents[0]);
if (ret < 0)
return ret;
+ (*job)->parents_filled = 0;
}
job_free(*job);
@@ -194,8 +190,7 @@ void queue_thread_free(struct queue_thread *queue_thread)
CIRCLEQ_FOREACH_FREE(cur, next, &queue_thread->queue->jobs, clist,
job_free);
- hdestroy_r(queue_thread->queue->htab);
- free(queue_thread->queue->htab);
+ htab_free(queue_thread->queue->htab);
ret = sem_destroy(&queue_thread->queue->sem);
if (ret < 0)
print_err("%s", strerror(errno));
@@ -234,25 +229,13 @@ int queue_thread_new(struct queue_thread **queue_thread, FILE *stream)
goto out_free_queue;
}
- qt->queue->htab = malloc(sizeof(*qt->queue->htab));
- if (qt->queue->htab == NULL) {
- print_err("%s", strerror(errno));
- ret = -errno;
+ ret = htab_init(&qt->queue->htab);
+ if (ret < 0)
goto out_free_sem;
- }
- ret = hcreate_r(MAX_NIX_PKG_COUNT, qt->queue->htab);
- if (ret == 0) {
- print_err("%s", strerror(errno));
- ret = -errno;
- goto out_free_htab;
- }
CIRCLEQ_INIT(&qt->queue->jobs);
pthread_mutex_init(&qt->queue->mutex, NULL);
-out_free_htab:
- if (ret < 0)
- free(qt->queue->htab);
out_free_sem:
if (ret < 0)
sem_destroy(&qt->queue->sem);