git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 5/5] (BROKEN) get_merge_bases_many(): walk from many tips in parallel

From
Junio C Hamano <gitster@pobox.com>
Date
Aug 27, 2012, 23:12 UTC
Message-ID
<1346109123-12357-6-git-send-email-gitster@pobox.com>
In-Reply-To
<1346109123-12357-1-git-send-email-gitster@pobox.com>

After merge_bases_many() paints the graph in two colors to find common ancestors, get_merge_bases_many() reduces the result by excluding commits that can be reached from other commits in the result. We used to do N * (N-1) traversals for this, but we can check if one commit is reachable from any of the other (N-1) commits by a single traversal, and repeat it N times to find the answer.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 commit.c | 42 +++++++++++++++++++++++-------------------
 1 file changed, 23 insertions(+), 19 deletions(-)
diff --git a/commit.c b/commit.c
index f5211bd..ccf2c5a 100644
--- a/commit.c
+++ b/commit.c
@@ -715,7 +715,7 @@ struct commit_list *get_merge_bases_many(struct commit *one,
 					 int cleanup)
 {
 	struct commit_list *list;
-	struct commit **rslt;
+	struct commit **rslt, **others;
 	struct commit_list *result;
 	int cnt, i, j;
 
@@ -744,33 +744,37 @@ struct commit_list *get_merge_bases_many(struct commit *one,
 	for (list = result, i = 0; list; list = list->next)
 		rslt[i++] = list->item;
 	free_commit_list(result);
+	result = NULL;
 
 	clear_commit_marks(one, all_flags);
 	for (i = 0; i < n; i++)
 		clear_commit_marks(twos[i], all_flags);
-	for (i = 0; i < cnt - 1; i++) {
-		for (j = i+1; j < cnt; j++) {
-			if (!rslt[i] || !rslt[j])
-				continue;
-			result = merge_bases_many(rslt[i], 1, &rslt[j]);
-			clear_commit_marks(rslt[i], all_flags);
-			clear_commit_marks(rslt[j], all_flags);
-			for (list = result; list; list = list->next) {
-				if (rslt[i] == list->item)
-					rslt[i] = NULL;
-				if (rslt[j] == list->item)
-					rslt[j] = NULL;
-			}
-		}
-	}
 
-	/* Surviving ones in rslt[] are the independent results */
-	result = NULL;
+	others = xcalloc(cnt - 1, sizeof(*others));
 	for (i = 0; i < cnt; i++) {
-		if (rslt[i])
+		/*
+		 * Is rslt[i] an ancestor of any of the others?
+		 * then it is not interesting to us.
+		 */
+		for (j = 0; j < i; j++)
+			others[j] = rslt[j];
+		for (j = 1 + 1; j < cnt; j++)
+			others[j - 1] = rslt[j];
+		list = merge_bases_many(rslt[i], cnt - 1, others);
+		clear_commit_marks(rslt[i], all_flags);
+		for (j = 0; j < cnt - 1; j++)
+			clear_commit_marks(others[j], all_flags);
+		while (list) {
+			if (rslt[i] == list->item)
+				break;
+			list = list->next;
+		}
+		if (!list)
 			commit_list_insert_by_date(rslt[i], &result);
+		free_commit_list(list);
 	}
 	free(rslt);
+	free(others);
 	return result;
 }
 
-- 
1.7.12.116.g31e0100
Previous: Junio C HamanoNext: Junio C Hamano
Message 6 of 27 in “optimize fast-forward checks”
  1. 0/5 optimize fast-forward checksJunio C Hamano, Aug 27, 2012
  2. 1/5 in_merge_bases(): support only one "other" commitJunio C Hamano, Aug 27, 2012
  3. 2/5 receive-pack: use in_merge_bases() for fast-forward checkJunio C Hamano, Aug 27, 2012
  4. 3/5 http-push: use in_merge_bases() for fast-forward checkJunio C Hamano, Aug 27, 2012
  5. 4/5 in_merge_bases(): omit unnecessary redundant common ancestor reductionJunio C Hamano, Aug 27, 2012
  6. 5/5 (BROKEN) get_merge_bases_many(): walk from many tips in parallelJunio C Hamano, Aug 27, 2012
  7. Junio C HamanoAug 28, 2012
  8. Junio C HamanoAug 28, 2012
  9. Junio C HamanoAug 28, 2012
  10. Jeff KingAug 29, 2012
  11. 1/2 basic priority queue implementationJeff King, Aug 29, 2012
  12. 2/2 commit: use a priority queue in merge base functionsJeff King, Aug 29, 2012
  13. Junio C HamanoAug 29, 2012
  14. Jeff KingAug 29, 2012
  15. Jeff KingAug 29, 2012
  16. Jeff KingAug 29, 2012
  17. Jeff KingAug 29, 2012
  18. Jeff KingAug 30, 2012
  19. Jeff KingAug 30, 2012
  20. Jeff KingAug 30, 2012
  21. Junio C HamanoAug 30, 2012
  22. Jeff KingAug 30, 2012
  23. Junio C HamanoAug 30, 2012
  24. Junio C HamanoAug 30, 2012
  25. Jeff KingAug 30, 2012
  26. Junio C HamanoAug 30, 2012
  27. Junio C HamanoAug 29, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.