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

Re: [PATCH 5/8] string-list: add pos to iterator callback

From
Jeff King <peff@peff.net>
Date
Jul 1, 2014, 19:00 UTC
Message-ID
<20140701190037.GA15828@sigill.intra.peff.net>
In-Reply-To
<xmqq1tu5x9ao.fsf@gitster.dls.corp.google.com>
On Tue, Jul 01, 2014 at 10:45:19AM -0700, Junio C Hamano wrote:
Show 11 quoted lines
> Jeff King <peff@peff.net> writes:
> 
> > When we are running a string-list foreach or filter, the
> > callback function sees only the string_list_item, along with
> > a void* data pointer provided by the caller. This is
> > sufficient for most purposes.
> >
> > However, it can also be useful to know the position of the
> > item within the string (for example, if the data pointer
> 
> s/the string/&-list/ (or s/&/&_list/).
Thanks, yeah.
Show 8 quoted lines
> While I can buy that some callers would want to learn the pos in the
> list, I am not sure if this is a good direction to go.  Primarily, I
> am having trouble sifting between "want" and "need".
> 
> How often do callers want to do this?  If only narrow specialized
> callers want this, is it unreasonable to ask them to add a "int ctr"
> in their cb_data and use "pos = ((struct theirs *)cb_data)->ctr++"
> in their callback instead?

Not all that often, I suppose (I only add one caller in this series). I just found it a little hack-ish to force callers to keep their own counter when we already have it (especially because it is not too hard to get it wrong, for example by forgetting to increment the counter in one code path of the callback).

Here's what the caller would look like without "pos" (done as a patch on top of the series, so pos is still there, but no longer used).

diff --git a/builtin/tag.c b/builtin/tag.c
index f17192c..dc6f105 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -151,14 +151,20 @@ static int util_is_not_null(struct string_list_item *it, int pos, void *data)
 	return !!it->util;
 }
 
-static int matches_contains(struct string_list_item *it, int pos, void *data)
+struct contains_callback_data {
+	int ctr;
+	unsigned char *contains;
+};
+
+static int matches_contains(struct string_list_item *it, int pos, void *vdata)
 {
-	unsigned char *contains = data;
-	return contains[pos];
+	struct contains_callback_data *data = vdata;
+	return data->contains[data->ctr++];
 }
 
 static void limit_by_contains(struct string_list *tags, struct commit_list *with)
 {
+	struct contains_callback_data cbdata;
 	struct commit_list *tag_commits = NULL, **tail = &tag_commits;
 	unsigned char *result;
 	int i;
@@ -180,7 +186,10 @@ static void limit_by_contains(struct string_list *tags, struct commit_list *with
 
 	result = xmalloc(tags->nr);
 	commit_contains(with, tag_commits, NULL, result);
-	filter_string_list(tags, 1, matches_contains, result);
+
+	cbdata.ctr = 0;
+	cbdata.contains = result;
+	filter_string_list(tags, 1, matches_contains, &cbdata);
 
 	free(result);
 	free_commit_list(tag_commits);

So I think it's a small change in a lot of places rather than a kind of
ugly change in one spot.

All that being said, I think the real issue here is that I want more
than a string list (I am already using the util field for the sha1, but
this code would be potentially simpler if I could also store the commit
object). In the long run I hope to factor out a ref-listing API that can
be used by tag, branch, and for-each-ref. And then this string-list code
would go away in favor of a more expansive struct. So it may not be
worth worrying about keeping it too clean.

-Peff
Previous: Junio C HamanoNext: Jeff King
Message 16 of 26 in “use merge-base for tag --contains”
  1. 0/8 use merge-base for tag --containsJeff King, Jun 25, 2014
  2. 1/8 tag: allow --sort with -nJeff King, Jun 25, 2014
  3. 2/8 tag: factor out decision to stream tagsJeff King, Jun 25, 2014
  4. 3/8 paint_down_to_common: use prio_queueJeff King, Jun 25, 2014
  5. Junio C HamanoJul 1, 2014
  6. Jeff KingJul 1, 2014
  7. 4/8 add functions for memory-efficient bitmapsJeff King, Jun 25, 2014
  8. Torsten BögershausenJun 26, 2014
  9. Jeff KingJun 26, 2014
  10. Eric SunshineJun 29, 2014
  11. Jeff KingJun 30, 2014
  12. Junio C HamanoJul 1, 2014
  13. Jeff KingJul 1, 2014
  14. 5/8 string-list: add pos to iterator callbackJeff King, Jun 25, 2014
  15. Junio C HamanoJul 1, 2014
  16. Jeff KingJul 1, 2014
  17. 6/8 commit: provide a fast multi-tip contains functionJeff King, Jun 25, 2014
  18. Junio C HamanoJun 26, 2014
  19. Junio C HamanoJun 26, 2014
  20. Junio C HamanoJun 26, 2014
  21. Junio C HamanoJul 1, 2014
  22. Junio C HamanoJul 1, 2014
  23. 7/8 tag: use commit_containsJeff King, Jun 25, 2014
  24. 8/8 perf: add tests for tag --containsJeff King, Jun 25, 2014
  25. Jeff KingJun 26, 2014
  26. Jeff KingJun 26, 2014

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.