All of lore.kernel.org
 help / color / mirror / Atom feed
From: mhagger@alum.mit.edu
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org, Jeff King <peff@peff.net>,
	Jakub Narebski <jnareb@gmail.com>,
	Heiko Voigt <hvoigt@hvoigt.net>,
	Johan Herland <johan@herland.net>,
	Michael Haggerty <mhagger@alum.mit.edu>
Subject: [PATCH 04/15] do_for_each_ref_in_arrays(): new function
Date: Tue, 10 Apr 2012 07:30:16 +0200	[thread overview]
Message-ID: <1334035827-20331-5-git-send-email-mhagger@alum.mit.edu> (raw)
In-Reply-To: <1334035827-20331-1-git-send-email-mhagger@alum.mit.edu>

From: Michael Haggerty <mhagger@alum.mit.edu>

Extract function do_for_each_ref_in_arrays() from do_for_each_ref().
The new function will be a useful building block for storing refs
hierarchically.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 refs.c |   82 +++++++++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 53 insertions(+), 29 deletions(-)

diff --git a/refs.c b/refs.c
index 263bd81..f9a1b57 100644
--- a/refs.c
+++ b/refs.c
@@ -288,6 +288,52 @@ static int do_for_each_ref_in_array(struct ref_array *array, int offset,
 }
 
 /*
+ * Call fn for each reference in the union of array1 and array2, in
+ * order by refname.  If an entry appears in both array1 and array2,
+ * then only process the version that is in array2.  The input arrays
+ * must already be sorted.
+ */
+static int do_for_each_ref_in_arrays(struct ref_array *array1,
+				     struct ref_array *array2,
+				     const char *base, each_ref_fn fn, int trim,
+				     int flags, void *cb_data)
+{
+	int retval;
+	int i1 = 0, i2 = 0;
+
+	assert(array1->sorted == array1->nr);
+	assert(array2->sorted == array2->nr);
+	while (i1 < array1->nr && i2 < array2->nr) {
+		struct ref_entry *e1 = array1->refs[i1];
+		struct ref_entry *e2 = array2->refs[i2];
+		int cmp = strcmp(e1->name, e2->name);
+		if (cmp < 0) {
+			retval = do_one_ref(base, fn, trim, flags, cb_data, e1);
+			i1++;
+		} else {
+			retval = do_one_ref(base, fn, trim, flags, cb_data, e2);
+			i2++;
+			if (cmp == 0) {
+				/*
+				 * There was a ref in array1 with the
+				 * same name; ignore it.
+				 */
+				i1++;
+			}
+		}
+		if (retval)
+			return retval;
+	}
+	if (i1 < array1->nr)
+		return do_for_each_ref_in_array(array1, i1,
+						base, fn, trim, flags, cb_data);
+	if (i2 < array2->nr)
+		return do_for_each_ref_in_array(array2, i2,
+						base, fn, trim, flags, cb_data);
+	return 0;
+}
+
+/*
  * Return true iff a reference named refname could be created without
  * conflicting with the name of an existing reference.  If oldrefname
  * is non-NULL, ignore potential conflicts with oldrefname (e.g.,
@@ -873,36 +919,14 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
 static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn fn,
 			   int trim, int flags, void *cb_data)
 {
-	int retval = 0, p = 0, l = 0;
 	struct ref_cache *refs = get_ref_cache(submodule);
-	struct ref_array *packed = get_packed_refs(refs);
-	struct ref_array *loose = get_loose_refs(refs);
-
-	sort_ref_array(packed);
-	sort_ref_array(loose);
-	while (p < packed->nr && l < loose->nr) {
-		struct ref_entry *entry;
-		int cmp = strcmp(packed->refs[p]->name, loose->refs[l]->name);
-		if (!cmp) {
-			p++;
-			continue;
-		}
-		if (cmp > 0) {
-			entry = loose->refs[l++];
-		} else {
-			entry = packed->refs[p++];
-		}
-		retval = do_one_ref(base, fn, trim, flags, cb_data, entry);
-		if (retval)
-			return retval;
-	}
-
-	if (l < loose->nr)
-		return do_for_each_ref_in_array(loose, l, base, fn, trim, flags, cb_data);
-	if (p < packed->nr)
-		return do_for_each_ref_in_array(packed, p, base, fn, trim, flags, cb_data);
-
-	return 0;
+	struct ref_array *packed_refs = get_packed_refs(refs);
+	struct ref_array *loose_refs = get_loose_refs(refs);
+	sort_ref_array(packed_refs);
+	sort_ref_array(loose_refs);
+	return do_for_each_ref_in_arrays(packed_refs,
+					 loose_refs,
+					 base, fn, trim, flags, cb_data);
 }
 
 static int do_head_ref(const char *submodule, each_ref_fn fn, void *cb_data)
-- 
1.7.10

  parent reply	other threads:[~2012-04-10  5:31 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-10  5:30 [PATCH 00/15] Hierarchical reference cache (once again) mhagger
2012-04-10  5:30 ` [PATCH 01/15] refs.c: reorder definitions more logically mhagger
2012-04-10  5:30 ` [PATCH 02/15] refs: manage current_ref within do_one_ref() mhagger
2012-04-10  5:30 ` [PATCH 03/15] do_for_each_ref_in_array(): new function mhagger
2012-04-10  5:30 ` mhagger [this message]
2012-04-10  5:30 ` [PATCH 05/15] repack_without_ref(): reimplement using do_for_each_ref_in_array() mhagger
2012-04-10  5:30 ` [PATCH 06/15] names_conflict(): new function, extracted from is_refname_available() mhagger
2012-04-10  5:30 ` [PATCH 07/15] names_conflict(): simplify implementation mhagger
2012-04-10  5:30 ` [PATCH 08/15] is_refname_available(): reimplement using do_for_each_ref_in_array() mhagger
2012-04-10  5:30 ` [PATCH 09/15] free_ref_entry(): new function mhagger
2012-04-10  5:30 ` [PATCH 10/15] check_refname_component(): return 0 for zero-length components mhagger
2012-04-10  5:30 ` [PATCH 11/15] struct ref_entry: nest the value part in a union mhagger
2012-04-10  5:30 ` [PATCH 12/15] refs.c: rename ref_array -> ref_dir mhagger
2012-04-10  5:30 ` [PATCH 13/15] sort_ref_dir(): simplify logic mhagger
2012-04-10  5:30 ` [PATCH 14/15] refs: store references hierarchically mhagger
2012-04-10  5:30 ` [PATCH 15/15] do_for_each_ref(): only iterate over the subtree that was requested mhagger
2012-04-12  6:44 ` [PATCH 00/15] Hierarchical reference cache (once again) Jeff King
2012-04-12 15:36   ` 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

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

  git send-email \
    --in-reply-to=1334035827-20331-5-git-send-email-mhagger@alum.mit.edu \
    --to=mhagger@alum.mit.edu \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=hvoigt@hvoigt.net \
    --cc=jnareb@gmail.com \
    --cc=johan@herland.net \
    --cc=peff@peff.net \
    /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.