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

[PATCH 4/8] git-remote-mediawiki: get rid of O(N^2) loop

From
Matthieu Moy <matthieu.moy@imag.fr>
Date
Jul 16, 2012, 19:46 UTC
Message-ID
<1342468002-31818-5-git-send-email-Matthieu.Moy@imag.fr>
In-Reply-To
<1342468002-31818-1-git-send-email-Matthieu.Moy@imag.fr>

The algorithm to find a path from the local revision to the remote one was calling "git rev-list" and parsing its output N times. Run rev-list only once, and fill a hashtable with the result to optimize the body of the loop.

Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
---
 contrib/mw-to-git/git-remote-mediawiki | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/contrib/mw-to-git/git-remote-mediawiki b/contrib/mw-to-git/git-remote-mediawiki
index 8e46e4e..fb1e9e0 100755
--- a/contrib/mw-to-git/git-remote-mediawiki
+++ b/contrib/mw-to-git/git-remote-mediawiki
@@ -1196,16 +1196,26 @@ sub mw_push_revision {
 	if ($last_local_revid > 0) {
 		my $parsed_sha1 = $remoteorigin_sha1;
 		# Find a path from last MediaWiki commit to pushed commit
+		print STDERR "Computing path from local to remote ...\n";
+		my @local_ancestry = split(/\n/, run_git("rev-list --boundary --parents $local ^$parsed_sha1"));
+		my %local_ancestry;
+		foreach my $line (@local_ancestry) {
+			if (my ($child, $parents) = $line =~ m/^-?([a-f0-9]+) ([a-f0-9 ]+)/) {
+				foreach my $parent (split(' ', $parents)) {
+					$local_ancestry{$parent} = $child;
+				}
+			} elsif (!$line =~ m/^([a-f0-9]+)/) {
+				die "Unexpected output from git rev-list: $line";
+			}
+		}
 		while ($parsed_sha1 ne $HEAD_sha1) {
-			my @commit_info =  grep(/^$parsed_sha1/, split(/\n/, run_git("rev-list --children $local")));
-			if (!@commit_info) {
+			my $child = $local_ancestry{$parsed_sha1};
+			if (!$child) {
+				printf STDERR "Cannot find a path in history from remote commit to last commit\n";
 				return error_non_fast_forward($remote);
 			}
-			my @commit_info_split = split(/ |\n/, $commit_info[0]);
-			# $commit_info_split[1] is the sha1 of the commit to export
-			# $commit_info_split[0] is the sha1 of its direct child
-			push(@commit_pairs, \@commit_info_split);
-			$parsed_sha1 = $commit_info_split[1];
+			push(@commit_pairs, [$parsed_sha1, $child]);
+			$parsed_sha1 = $child;
 		}
 	} else {
 		# No remote mediawiki revision. Export the whole
-- 
1.7.11.2.258.g5ff3cdf.dirty
Previous: Matthieu MoyNext: Matthieu Moy
Message 23 of 33 in “git-remote-mediawiki: fixes, optimizations, and progress report”
  1. 0/8 git-remote-mediawiki: fixes, optimizations, and progress reportMatthieu Moy, Jul 16, 2012
  2. 1/8 git-remote-mediawiki: don't split namespaces with spacesMatthieu Moy, Jul 16, 2012
  3. Junio C HamanoJul 16, 2012
  4. 2/8 git-remote-mediawiki: actually send empty comment when they're emptyMatthieu Moy, Jul 16, 2012
  5. Junio C HamanoJul 16, 2012
  6. Matthieu MoyJul 16, 2012
  7. Junio C HamanoJul 16, 2012
  8. 3/8 git-remote-mediawiki: make mediafiles export optionalMatthieu Moy, Jul 16, 2012
  9. Junio C HamanoJul 16, 2012
  10. Matthieu MoyJul 16, 2012
  11. 4/8 git-remote-mediawiki: get rid of O(N^2) loopMatthieu Moy, Jul 16, 2012
  12. Junio C HamanoJul 16, 2012
  13. Matthieu MoyJul 16, 2012
  14. 5/8 git-remote-mediawiki: use --force when adding notesMatthieu Moy, Jul 16, 2012
  15. 6/8 git-remote-mediawiki: show progress information when listing pagesMatthieu Moy, Jul 16, 2012
  16. 7/8 git-remote-mediawiki: show progress information when getting last remote revisionMatthieu Moy, Jul 16, 2012
  17. 8/8 git-remote-mediawiki: properly deal with invalid remote revisionsMatthieu Moy, Jul 16, 2012
  18. Junio C HamanoJul 16, 2012
  19. 0/8 git-remote-mediawiki: fixes, optimizations, and progress reportMatthieu Moy, Jul 16, 2012
  20. 1/8 git-remote-mediawiki: don't split namespaces with spacesMatthieu Moy, Jul 16, 2012
  21. 2/8 git-remote-mediawiki: actually send empty comment when they're emptyMatthieu Moy, Jul 16, 2012
  22. 3/8 git-remote-mediawiki: make mediafiles export optionalMatthieu Moy, Jul 16, 2012
  23. 4/8 git-remote-mediawiki: get rid of O(N^2) loopMatthieu Moy, Jul 16, 2012
  24. 5/8 git-remote-mediawiki: use --force when adding notesMatthieu Moy, Jul 16, 2012
  25. 6/8 git-remote-mediawiki: show progress information when listing pagesMatthieu Moy, Jul 16, 2012
  26. 7/8 git-remote-mediawiki: show progress information when getting last remote revisionMatthieu Moy, Jul 16, 2012
  27. 8/8 git-remote-mediawiki: properly deal with invalid remote revisionsMatthieu Moy, Jul 16, 2012
  28. Junio C HamanoJul 16, 2012
  29. 0/2 git-remote-mediawiki: two more fixesMatthieu Moy, Jul 17, 2012
  30. 1/2 git-remote-mediawiki: fix incorrect test usage in testMatthieu Moy, Jul 17, 2012
  31. 2/2 git-remote-mediawiki: allow page names with a ':'Matthieu Moy, Jul 17, 2012
  32. Dan JohnsonJul 20, 2012
  33. Matthieu MoyJul 23, 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.