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

[RFC PATCH v3 1/2] fetch-pack: rearrange main loop

From
Thomas Rast <trast@student.ethz.ch>
Date
Dec 6, 2008, 23:20 UTC
Message-ID
<1228605621-29685-2-git-send-email-trast@student.ethz.ch>
In-Reply-To
<1228605621-29685-1-git-send-email-trast@student.ethz.ch>

This patch does not change the results (nor any of the semantics except for the get_rev return type), but we need the changed layout for the exponential-stride feature.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 builtin-fetch-pack.c |  108 +++++++++++++++++++++++++++++--------------------
 1 files changed, 64 insertions(+), 44 deletions(-)
diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c
index 372bfa2..ae0a67a 100644
--- a/builtin-fetch-pack.c
+++ b/builtin-fetch-pack.c
@@ -111,7 +111,7 @@ static void mark_common(struct commit *commit,
   Get the next rev to send, ignoring the common.
 */
 
-static const unsigned char* get_rev(void)
+static struct commit* get_rev(void)
 {
 	struct commit *commit = NULL;
 
@@ -153,15 +153,41 @@ static const unsigned char* get_rev(void)
 		rev_list = rev_list->next;
 	}
 
-	return commit->object.sha1;
+	return commit;
 }
 
+/*
+ * Send 'have' for the next batch of revisions.  Returns 0 if we ran
+ * out of commits to send, 1 otherwise.
+ */
+
+static int send_have_lines(int fd[2], int *flushes, unsigned *in_vain)
+{
+	struct commit *commit;
+	int i;
+
+	for (i = 0; i < 32; i++) {
+		commit = get_rev();
+		if (!commit)
+			return 0;
+		packet_write(fd[1], "have %s\n",
+			     sha1_to_hex(commit->object.sha1));
+		if (args.verbose)
+			fprintf(stderr, "have %s\n",
+				sha1_to_hex(commit->object.sha1));
+	}
+	packet_flush(fd[1]);
+	*flushes += 1;
+	*in_vain += 32;
+	return 1;
+}
+
+
 static int find_common(int fd[2], unsigned char *result_sha1,
 		       struct ref *refs)
 {
 	int fetching;
 	int count = 0, flushes = 0, retval;
-	const unsigned char *sha1;
 	unsigned in_vain = 0;
 	int got_continue = 0;
 
@@ -243,51 +269,45 @@ static int find_common(int fd[2], unsigned char *result_sha1,
 
 	flushes = 0;
 	retval = -1;
-	while ((sha1 = get_rev())) {
-		packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
-		if (args.verbose)
-			fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
-		in_vain++;
-		if (!(31 & ++count)) {
-			int ack;
 
-			packet_flush(fd[1]);
-			flushes++;
+	/*
+	 * We keep one window "ahead" of the other side, and
+	 * will wait for an ACK only on the next one
+	 */
+	if (!send_have_lines(fd, &flushes, &in_vain))
+		goto done;
 
-			/*
-			 * We keep one window "ahead" of the other side, and
-			 * will wait for an ACK only on the next one
-			 */
-			if (count == 32)
-				continue;
+	while (send_have_lines(fd, &flushes, &in_vain)) {
+		int ack;
+		int unwound = 0;
 
-			do {
-				ack = get_ack(fd[0], result_sha1);
-				if (args.verbose && ack)
-					fprintf(stderr, "got ack %d %s\n", ack,
-							sha1_to_hex(result_sha1));
-				if (ack == 1) {
-					flushes = 0;
-					multi_ack = 0;
-					retval = 0;
-					goto done;
-				} else if (ack == 2) {
-					struct commit *commit =
-						lookup_commit(result_sha1);
-					mark_common(commit, 0, 1);
-					retval = 0;
-					in_vain = 0;
-					got_continue = 1;
-				}
-			} while (ack);
-			flushes--;
-			if (got_continue && MAX_IN_VAIN < in_vain) {
-				if (args.verbose)
-					fprintf(stderr, "giving up\n");
-				break; /* give up */
+		do {
+			ack = get_ack(fd[0], result_sha1);
+			if (args.verbose && ack)
+				fprintf(stderr, "got ack %d %s\n", ack,
+					sha1_to_hex(result_sha1));
+			if (ack == 1) {
+				flushes = 0;
+				multi_ack = 0;
+				retval = 0;
+				goto done;
+			} else if (ack == 2) {
+				struct commit *commit =
+					lookup_commit(result_sha1);
+				mark_common(commit, 0, 1);
+				retval = 0;
+				in_vain = 0;
+				got_continue = 1;
 			}
+		} while (ack);
+		flushes--;
+		if (got_continue && MAX_IN_VAIN < in_vain) {
+			if (args.verbose)
+				fprintf(stderr, "giving up\n");
+			break; /* give up */
 		}
 	}
+
 done:
 	packet_write(fd[1], "done\n");
 	if (args.verbose)
-- 
tg: (7f705dc..) t/fp-refactor (depends on: origin/master)
Previous: Thomas RastNext: Thomas Rast
Message 11 of 13 in “[RFC] log(n)-transmissions common commit handshake”
  1. Thomas RastSep 17, 2008
  2. fetch-pack: log(n)-transmission find_common()Thomas Rast, Sep 17, 2008
  3. fetch-pack: log(n)-transmission find_common()Thomas Rast, Sep 24, 2008
  4. fetch-pack: log(n)-transmission find_common()Thomas Rast, Oct 23, 2008
  5. Nicolas PitreOct 24, 2008
  6. Nanako ShiraishiOct 27, 2008
  7. Junio C HamanoOct 28, 2008
  8. Nicolas PitreOct 28, 2008
  9. Thomas RastOct 28, 2008
  10. 0/2 fetch-pack: log(n)-transmission find_common()Thomas Rast, Dec 6, 2008
  11. 1/2 fetch-pack: rearrange main loopThomas Rast, Dec 6, 2008
  12. 2/2 fetch-pack: log(n)-transmission find_common()Thomas Rast, Dec 6, 2008
  13. Thomas RastSep 18, 2008

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.