All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mirko Faina <mroik@delayed.space>
To: git@vger.kernel.org
Cc: "Mirko Faina" <mroik@delayed.space>,
	"Junio C Hamano" <gitster@pobox.com>, "Jeff King" <peff@peff.net>,
	"Jean-Noël Avila" <jn.avila@free.fr>,
	"Patrick Steinhardt" <ps@pks.im>, "Tian Yuchen" <cat@malon.dev>,
	"Ben Knoble" <ben.knoble@gmail.com>
Subject: [PATCH v2 2/2] revision.c: reduce memory usage on reverse before
Date: Wed, 22 Apr 2026 02:28:41 +0200	[thread overview]
Message-ID: <20260422002840.303477-6-mroik@delayed.space> (raw)
In-Reply-To: <20260418164736.2367523-2-mroik@delayed.space>

Due to the nature of --reverse=before we have to walk all of the history
and store each non-filtered processed commit, this can be expensive on
memory for projects with a long history. When --max-count is being used
we don't really have to keep every processed commit, we can discard
older commits (as in have been processed before than the ones we're now
considering, from a chronological commit order they are the newer
commits) as we surpass the --max-count limit.

Teach get_revision() to keep only the newer commits as we walk a
revision with --reverse=before and --max-count=<k>. We do this through a
simple queue. With N nodes and K as the --max-count argument, assuming K
< N, we go from a space complexity of O(N) to O(K). When it comes down
to time complexity, the queue has an ammortized time of O(1) for pops,
so the complexity remains O(N).

Signed-off-by: Mirko Faina <mroik@delayed.space>
---
 revision.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 52 insertions(+), 2 deletions(-)

diff --git a/revision.c b/revision.c
index d581f5e38e..4730f21ea6 100644
--- a/revision.c
+++ b/revision.c
@@ -4530,6 +4530,52 @@ static struct commit *get_revision_internal(struct rev_info *revs)
 	return c;
 }
 
+static void retrieve_with_window(struct rev_info *revs, int max_count,
+			  struct commit_list **reversed)
+{
+	struct commit *c;
+	struct commit_list *into_queue = NULL;
+	struct commit_list *outo_queue = NULL;
+	int into_count = 0;
+	int outo_count = 0;
+
+	while ((c = get_revision_internal(revs))) {
+		commit_list_insert(c, &into_queue);
+		into_count++;
+		if (into_count + outo_count > max_count) {
+			if (!outo_count) {
+				while (into_count) {
+					c = pop_commit(&into_queue);
+					into_count--;
+					commit_list_insert(c, &outo_queue);
+					outo_count++;
+				}
+			}
+			pop_commit(&outo_queue);
+			outo_count--;
+		}
+	}
+
+	while (outo_count) {
+		c = pop_commit(&outo_queue);
+		outo_count--;
+		commit_list_insert(c, reversed);
+	}
+
+	while (into_count) {
+		c = pop_commit(&into_queue);
+		into_count--;
+		commit_list_insert(c, &outo_queue);
+		outo_count++;
+	}
+
+	while (outo_count) {
+		c = pop_commit(&outo_queue);
+		outo_count--;
+		commit_list_insert(c, reversed);
+	}
+}
+
 struct commit *get_revision(struct rev_info *revs)
 {
 	struct commit *c;
@@ -4546,8 +4592,12 @@ struct commit *get_revision(struct rev_info *revs)
 			revs->max_count = -1;
 
 		reversed = NULL;
-		while ((c = get_revision_internal(revs)))
-			commit_list_insert(c, &reversed);
+		if (revs->reverse == REVERSE_BEFORE && max_count != -1) {
+			retrieve_with_window(revs, max_count, &reversed);
+		} else {
+			while ((c = get_revision_internal(revs)))
+				commit_list_insert(c, &reversed);
+		}
 		commit_list_free(revs->commits);
 		revs->commits = reversed;
 		revs->reverse_output_stage = 1;
-- 
2.54.0


      parent reply	other threads:[~2026-04-22  0:29 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-18 16:47 [PATCH] revision.c: implement --reverse=before for walks Mirko Faina
2026-04-18 18:20 ` Tian Yuchen
2026-04-18 18:42   ` Mirko Faina
2026-04-18 18:51     ` Mirko Faina
2026-04-20 16:06   ` Junio C Hamano
2026-04-20 17:08     ` Tian Yuchen
2026-04-20 23:50     ` Mirko Faina
2026-04-19 12:06 ` Ben Knoble
2026-04-19 18:11   ` Mirko Faina
2026-04-19 19:12     ` D. Ben Knoble
2026-04-19 20:31       ` Mirko Faina
2026-04-20  0:21         ` Jeff King
2026-04-20  9:33           ` Mirko Faina
2026-04-20 10:30             ` Mirko Faina
2026-04-21  3:48             ` Jeff King
2026-04-22 18:24         ` D. Ben Knoble
2026-04-22 19:42           ` Mirko Faina
2026-04-20  0:04 ` Jeff King
2026-04-20  9:22   ` Mirko Faina
2026-04-22  0:28 ` [PATCH v2 0/2] " Mirko Faina
2026-04-22  0:30   ` Mirko Faina
2026-04-23 22:51   ` [PATCH v3 " Mirko Faina
2026-04-23 22:51     ` [PATCH v3 1/2] " Mirko Faina
2026-04-28  1:45       ` Junio C Hamano
2026-04-23 22:52     ` [PATCH v3 2/2] revision.c: reduce memory usage on reverse before Mirko Faina
2026-04-27  0:24     ` [PATCH v4 0/2] revision.c: implement --reverse=before for walks Mirko Faina
2026-04-27  0:24       ` [PATCH v4 1/2] " Mirko Faina
2026-04-27  6:45         ` Junio C Hamano
2026-04-27  7:33           ` Johannes Sixt
2026-04-27 12:30             ` Junio C Hamano
2026-04-27 13:58               ` Chris Torek
2026-04-27 16:48           ` [PATCH v4 1/2] revision.c: implement -b-reverse=before " Mirko Faina
2026-04-28  1:46             ` Junio C Hamano
2026-04-28  1:45         ` [PATCH v4 1/2] revision.c: implement --reverse=before " Junio C Hamano
2026-04-27  0:24       ` [PATCH v4 2/2] revision.c: reduce memory usage on reverse before Mirko Faina
2026-04-28  1:46         ` Junio C Hamano
2026-04-30 19:52       ` [PATCH v5] revision.c: implement --max-count-oldest Mirko Faina
2026-05-04  5:19         ` Junio C Hamano
2026-05-04 13:08           ` Mirko Faina
2026-05-05 21:54         ` [PATCH v6] " Mirko Faina
2026-05-06  6:45           ` Johannes Sixt
2026-05-06 12:54             ` Mirko Faina
2026-05-07  9:20               ` Junio C Hamano
2026-05-08  0:09                 ` Mirko Faina
2026-05-09 12:46           ` Jean-Noël AVILA
2026-05-10  0:41             ` Mirko Faina
2026-05-09 21:01           ` Junio C Hamano
2026-05-10  0:48             ` Mirko Faina
2026-05-09 11:01         ` [PATCH v5] " Junio C Hamano
2026-05-10  0:36           ` Mirko Faina
2026-04-22  0:28 ` [PATCH v2 1/2] revision.c: implement --reverse=before for walks Mirko Faina
2026-04-22 22:44   ` Jeff King
2026-04-22 22:53     ` Mirko Faina
2026-04-22  0:28 ` Mirko Faina [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260422002840.303477-6-mroik@delayed.space \
    --to=mroik@delayed.space \
    --cc=ben.knoble@gmail.com \
    --cc=cat@malon.dev \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jn.avila@free.fr \
    --cc=peff@peff.net \
    --cc=ps@pks.im \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.