git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Ramkumar Ramachandra <artagnon@gmail.com>
To: Git List <git@vger.kernel.org>
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>,
	"Junio C Hamano" <gitster@pobox.com>
Subject: [PATCH v2 13/15] for-each-ref: improve responsiveness of %(upstream:track)
Date: Sun,  9 Jun 2013 23:24:32 +0530	[thread overview]
Message-ID: <1370800474-8940-14-git-send-email-artagnon@gmail.com> (raw)
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

  parent reply	other threads:[~2013-06-09 17:57 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-09 17:54 [PATCH v2 00/15] Towards a more awesome git branch Ramkumar Ramachandra
2013-06-09 17:54 ` [PATCH v2 01/15] for-each-ref, quote: convert *_quote_print -> *_quote_buf Ramkumar Ramachandra
2013-06-09 17:54 ` [PATCH v2 02/15] for-each-ref: don't print out elements directly Ramkumar Ramachandra
2013-06-09 17:54 ` [PATCH v2 03/15] tar-tree: remove dependency on sq_quote_print() Ramkumar Ramachandra
2013-06-09 17:54 ` [PATCH v2 04/15] quote: remove sq_quote_print() Ramkumar Ramachandra
2013-06-09 17:54 ` [PATCH v2 05/15] pretty: extend pretty_print_context with callback Ramkumar Ramachandra
2013-06-09 17:54 ` [PATCH v2 06/15] pretty: limit recursion in format_commit_one() Ramkumar Ramachandra
2013-06-09 17:54 ` [PATCH v2 07/15] pretty: allow passing NULL commit to format_commit_message() Ramkumar Ramachandra
2013-06-09 17:54 ` [PATCH v2 08/15] for-each-ref: get --pretty using format_commit_message() Ramkumar Ramachandra
2013-06-09 17:54 ` [PATCH v2 09/15] for-each-ref: teach verify_format() about pretty's syntax Ramkumar Ramachandra
2013-06-09 17:54 ` [PATCH v2 10/15] for-each-ref: introduce format specifier %>(*) and %<(*) Ramkumar Ramachandra
2013-06-09 17:54 ` [PATCH v2 11/15] for-each-ref: introduce %(HEAD) marker Ramkumar Ramachandra
2013-06-09 17:54 ` [PATCH v2 12/15] for-each-ref: introduce %(upstream:track[short]) Ramkumar Ramachandra
2013-06-09 17:54 ` Ramkumar Ramachandra [this message]
2013-06-09 17:54 ` [PATCH v2 14/15] pretty: introduce get_pretty_userformat Ramkumar Ramachandra
2013-06-09 17:54 ` [PATCH v2 15/15] for-each-ref: use get_pretty_userformat in --pretty Ramkumar Ramachandra
2013-06-10  1:25 ` [PATCH v2 00/15] Towards a more awesome git branch Duy Nguyen
2013-06-10 12:08   ` Ramkumar Ramachandra
2013-06-10 16:02     ` Junio C Hamano

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

  List information: http://vger.kernel.org/majordomo-info.html

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

  git send-email \
    --in-reply-to=1370800474-8940-14-git-send-email-artagnon@gmail.com \
    --to=artagnon@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=pclouds@gmail.com \
    /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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).