diff options
Diffstat (limited to 'src/queue.c')
-rw-r--r-- | src/queue.c | 141 |
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); |