commit 0a618912c7bba9bfab2be331204824e4bba303c3 from: Stefan Sperling date: Fri Jan 27 08:20:24 2023 UTC avoid traversing enumerated commits more than once in got-read-pack Keep track of parent commits that will be processed as part of looping over the commit queue provided by the main process, and do not add these commits to the queue again. Fixes pointless traversal of commits on the queue which will simply be skipped. The end result is the same either way. ok tracey commit - e1380e2807453e7f6feedf4b930146b511620427 commit + 0a618912c7bba9bfab2be331204824e4bba303c3 blob - 6f44f1ef778cf17b70dc0b2fb6bc9ae2a49a0ff3 blob + cd5bce6f2ef11d44d4fdf5b929d094051d59464c --- libexec/got-read-pack/got-read-pack.c +++ libexec/got-read-pack/got-read-pack.c @@ -1019,7 +1019,8 @@ recv_object_ids(struct got_object_idset *idset, struct } static const struct got_error * -recv_object_id_queue(struct got_object_id_queue *queue, struct imsgbuf *ibuf) +recv_object_id_queue(struct got_object_id_queue *queue, + struct got_object_idset *queued_ids, struct imsgbuf *ibuf) { const struct got_error *err = NULL; int done = 0; @@ -1037,6 +1038,9 @@ recv_object_id_queue(struct got_object_id_queue *queue return err; memcpy(&qid->id, &ids[i], sizeof(qid->id)); STAILQ_INSERT_TAIL(queue, qid, entry); + err = got_object_idset_add(queued_ids, &qid->id, NULL); + if (err) + return err; } } @@ -1362,7 +1366,7 @@ enumeration_request(struct imsg *imsg, struct imsgbuf struct got_commit_object *commit = NULL; struct got_object_id *tree_id = NULL; size_t totlen = 0; - struct got_object_idset *idset; + struct got_object_idset *idset, *queued_ids = NULL; int i, idx, have_all_entries = 1; struct enumerated_tree *trees = NULL; size_t ntrees = 0, nalloc = 16; @@ -1379,7 +1383,13 @@ enumeration_request(struct imsg *imsg, struct imsgbuf goto done; } - err = recv_object_id_queue(&commit_ids, ibuf); + queued_ids = got_object_idset_alloc(); + if (queued_ids == NULL) { + err = got_error_from_errno("got_object_idset_alloc"); + goto done; + } + + err = recv_object_id_queue(&commit_ids, queued_ids, ibuf); if (err) goto done; @@ -1497,6 +1507,8 @@ enumeration_request(struct imsg *imsg, struct imsgbuf STAILQ_FOREACH(pid, parents, entry) { if (got_object_idset_contains(idset, &pid->id)) continue; + if (got_object_idset_contains(queued_ids, &pid->id)) + continue; err = got_object_qid_alloc_partial(&qid); if (err) goto done; @@ -1528,6 +1540,8 @@ done: got_object_id_queue_free(&commit_ids); if (idset) got_object_idset_free(idset); + if (queued_ids) + got_object_idset_free(queued_ids); for (i = 0; i < ntrees; i++) { struct enumerated_tree *tree = &trees[i]; free(tree->buf);