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

[PATCH v2 13/15] for-each-ref: improve responsiveness of %(upstream:track)

From
Ramkumar Ramachandra <artagnon@gmail.com>
Date
Jun 9, 2013, 17:54 UTC
Message-ID
<1370800474-8940-14-git-send-email-artagnon@gmail.com>
In-Reply-To
<1370800474-8940-1-git-send-email-artagnon@gmail.com>
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>

Before anything is printed, for-each-ref sorts all refs first. As part of the sorting, populate_value() is called to fill the values in for all atoms/placeholders per entry. By the time sort_refs() is done, pretty much all data is already retrieved.

This works fine when data can be cheaply retrieved before %(upstream:track) comes into the picture. It may take a noticeable amount of time to process %(upstream:track) for each entry. All entries add up and make --format='%(refname)%(upstream:track)' seem hung for a few seconds, then display everything at once.

Improve the responsiveness by only processing the one atom (*) at a time so that processing one atom for all entries (e.g. sorting) won't cause much delay (unless you choose a "heavy" atom to process).

(*) This is not entirely correct. If you sort by an atom that needs object database access, then it will fill all atoms that need odb. Which is not a bad thing. We don't want to access odb once at sorting phase and again at display phase.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
 builtin/for-each-ref.c | 49 +++++++++++++++++++++++++------------------------
 1 file changed, 25 insertions(+), 24 deletions(-)
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index 72b33ee..25764aa 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -565,20 +565,6 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj
 }
 
 /*
- * We want to have empty print-string for field requests
- * that do not apply (e.g. "authordate" for a tag object)
- */
-static void fill_missing_values(struct atom_value *val)
-{
-	int i;
-	for (i = 0; i < used_atom_cnt; i++) {
-		struct atom_value *v = &val[i];
-		if (v->s == NULL)
-			v->s = "";
-	}
-}
-
-/*
  * val is a list of atom_value to hold returned values.  Extract
  * the values for atoms in used_atom array out of (obj, buf, sz).
  * when deref is false, (obj, buf, sz) is the object that is
@@ -621,7 +607,7 @@ static inline char *copy_advance(char *dst, const char *src)
 /*
  * Parse the object referred by ref, and grab needed value.
  */
-static void populate_value(struct refinfo *ref)
+static void populate_value(struct refinfo *ref, int only_this_atom)
 {
 	void *buf;
 	struct object *obj;
@@ -630,13 +616,15 @@ static void populate_value(struct refinfo *ref)
 	const unsigned char *tagged;
 	int upstream_present = 0;
 
-	ref->value = xcalloc(sizeof(struct atom_value), used_atom_cnt);
+	if (!ref->value) {
+		ref->value = xcalloc(sizeof(struct atom_value), used_atom_cnt);
 
-	if (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {
-		unsigned char unused1[20];
-		ref->symref = resolve_refdup(ref->refname, unused1, 1, NULL);
-		if (!ref->symref)
-			ref->symref = "";
+		if (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {
+			unsigned char unused1[20];
+			ref->symref = resolve_refdup(ref->refname, unused1, 1, NULL);
+			if (!ref->symref)
+				ref->symref = "";
+		}
 	}
 
 	/* Fill in specials first */
@@ -648,6 +636,9 @@ static void populate_value(struct refinfo *ref)
 		const char *formatp;
 		struct branch *branch;
 
+		if (only_this_atom != -1 && only_this_atom != i)
+			continue;
+
 		if (*name == '*') {
 			deref = 1;
 			name++;
@@ -754,6 +745,10 @@ static void populate_value(struct refinfo *ref)
 
 	for (i = 0; i < used_atom_cnt; i++) {
 		struct atom_value *v = &ref->value[i];
+
+		if (only_this_atom != -1 && only_this_atom != i)
+			continue;
+
 		if (v->s == NULL)
 			goto need_obj;
 	}
@@ -809,9 +804,15 @@ static void populate_value(struct refinfo *ref)
  */
 static void get_value(struct refinfo *ref, int atom, struct atom_value **v)
 {
-	if (!ref->value) {
-		populate_value(ref);
-		fill_missing_values(ref->value);
+	if (!ref->value || !ref->value[atom].s) {
+		populate_value(ref, atom);
+		/*
+		 * We want to have empty print-string for field
+		 * requests that do not apply (e.g. "authordate" for a
+		 * tag object)
+		 */
+		if (!ref->value[atom].s)
+			ref->value[atom].s = "";
 	}
 	*v = &ref->value[atom];
 }
-- 
1.8.3.247.g485169c
Previous: Ramkumar RamachandraNext: Ramkumar Ramachandra
Message 14 of 19 in “Towards a more awesome git branch”
  1. 00/15 Towards a more awesome git branchRamkumar Ramachandra, Jun 9, 2013
  2. 01/15 for-each-ref, quote: convert *_quote_print -> *_quote_bufRamkumar Ramachandra, Jun 9, 2013
  3. 02/15 for-each-ref: don't print out elements directlyRamkumar Ramachandra, Jun 9, 2013
  4. 03/15 tar-tree: remove dependency on sq_quote_print()Ramkumar Ramachandra, Jun 9, 2013
  5. 04/15 quote: remove sq_quote_print()Ramkumar Ramachandra, Jun 9, 2013
  6. 05/15 pretty: extend pretty_print_context with callbackRamkumar Ramachandra, Jun 9, 2013
  7. 06/15 pretty: limit recursion in format_commit_one()Ramkumar Ramachandra, Jun 9, 2013
  8. 07/15 pretty: allow passing NULL commit to format_commit_message()Ramkumar Ramachandra, Jun 9, 2013
  9. 08/15 for-each-ref: get --pretty using format_commit_message()Ramkumar Ramachandra, Jun 9, 2013
  10. 09/15 for-each-ref: teach verify_format() about pretty's syntaxRamkumar Ramachandra, Jun 9, 2013
  11. 10/15 for-each-ref: introduce format specifier %>(*) and %<(*)Ramkumar Ramachandra, Jun 9, 2013
  12. 11/15 for-each-ref: introduce %(HEAD) markerRamkumar Ramachandra, Jun 9, 2013
  13. 12/15 for-each-ref: introduce %(upstream:track[short])Ramkumar Ramachandra, Jun 9, 2013
  14. 13/15 for-each-ref: improve responsiveness of %(upstream:track)Ramkumar Ramachandra, Jun 9, 2013
  15. 14/15 pretty: introduce get_pretty_userformatRamkumar Ramachandra, Jun 9, 2013
  16. 15/15 for-each-ref: use get_pretty_userformat in --prettyRamkumar Ramachandra, Jun 9, 2013
  17. Duy NguyenJun 10, 2013
  18. Ramkumar RamachandraJun 10, 2013
  19. Junio C HamanoJun 10, 2013

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.