Web lists-archives.com

Re: [PATCH v3 2/5] fetch-pack: load tip_oids eagerly iff needed




On Fri, Oct 05, 2018 at 10:13:34PM +0200, René Scharfe wrote:

> >> -{
> >> -	/*
> >> -	 * Note that this only looks at the ref lists the first time it's
> >> -	 * called. This works out in filter_refs() because even though it may
> >> -	 * add to "newlist" between calls, the additions will always be for
> >> -	 * oids that are already in the set.
> >> -	 */
> > 
> > I don't think the subtle point this comment is making goes away. We're
> > still growing the list in the loop that calls tip_oids_contain() (and
> > which now calls just oidset_contains). That's OK for the reasons given
> > here, but I think that would need to be moved down to this code:
> > 
> >> +	if (strict) {
> >> +		for (i = 0; i < nr_sought; i++) {
> >> +			ref = sought[i];
> >> +			if (!is_unmatched_ref(ref))
> >> +				continue;
> >> +
> >> +			add_refs_to_oidset(&tip_oids, unmatched);
> >> +			add_refs_to_oidset(&tip_oids, newlist);
> >> +			break;
> >> +		}
> >> +	}
> > 
> > I.e., we need to say here why it's OK to summarize newlist in the
> > oidset, even though we're adding to it later.
> 
> There is already this comment:
> 
> 	/* Append unmatched requests to the list */
> 
> And that's enough in my eyes.  The refs loop at the top splits the list
> into matched ("the list") and unmatched, and the loop below said comment
> adds a few more.  I see no subtlety left -- what do I miss?

It looks like tip_oids is meant as a fast lookup into what's in
unmatched and newlist. But in the second loop we continue appending to
newlist. Why is it OK that we do not update tip_oids when we do so?

I.e., something like this explains it:

diff --git a/fetch-pack.c b/fetch-pack.c
index 53914563b5..c0a1b80f4c 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -606,6 +606,12 @@ static void filter_refs(struct fetch_pack_args *args,
 			ref->match_status = REF_MATCHED;
 			*newtail = copy_ref(ref);
 			newtail = &(*newtail)->next;
+			/*
+			 * No need to update tip_oids with ref->old_oid; we got
+			 * here because either it was already there, or we are
+			 * in !strict mode, in which case we do not use
+			 * tip_oids at all.
+			 */
 		} else {
 			ref->match_status = REF_UNADVERTISED_NOT_ALLOWED;
 		}