commit 47f028303ca0cb504743f84d2658e815f23ae53b from: Stefan Sperling via: Thomas Adam date: Fri Jan 27 16:48:21 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 - 4088ab23bf2d330dc66483a747e0efb6c185eed8 commit + 47f028303ca0cb504743f84d2658e815f23ae53b blob - d9a0d79f6f8a04fd392ed4bdd60090f2d26c73ab blob + 2d8a494fd6985be88a80609324aa75abab76b77d --- 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);