fetch-pack: make negotiation-related vars local

Reduce the number of global variables by making the priority queue and the count of non-common commits in it local, passing them as a struct to various functions where necessary. This also helps in the case that fetch_pack() is invoked twice in the same process (when tag following is required when using a transport that does not support tag following), in that different priority queues will now be used in each invocation, instead of reusing the possibly non-empty one. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Tan committed Jun 14, 2018 at 15:54 UTC d30fe89c37b746ac2f3419ae0e3990a9984fb4cf
1 file changed +69 -47
fetch-pack.c
+69 -47
@@ -50,8 +50,12 @@ static int marked;
50 */
51 #define MAX_IN_VAIN 256
52
53 -static struct prio_queue rev_list = { compare_commits_by_commit_date };
54 -static int non_common_revs, multi_ack, use_sideband;
53 +struct negotiation_state {
54 + struct prio_queue rev_list;
55 + int non_common_revs;
56 +};
57 +
58 +static int multi_ack, use_sideband;
59 /* Allow specifying sha1 if it is a ref tip. */
60 #define ALLOW_TIP_SHA1 01
61 /* Allow request of a sha1 if it is reachable from a ref (possibly hidden ref). */
@@ -93,7 +97,9 @@ static void cache_one_alternate(const char *refname,
97 cache->items[cache->nr++] = obj;
98 }
99
96 -static void for_each_cached_alternate(void (*cb)(struct object *))
100 +static void for_each_cached_alternate(struct negotiation_state *ns,
101 + void (*cb)(struct negotiation_state *,
102 + struct object *))
103 {
104 static int initialized;
105 static struct alternate_object_cache cache;
@@ -105,10 +111,11 @@ static void for_each_cached_alternate(void (*cb)(struct object *))
111 }
112
113 for (i = 0; i < cache.nr; i++)
108 - cb(cache.items[i]);
114 + cb(ns, cache.items[i]);
115 }
116
111 -static void rev_list_push(struct commit *commit, int mark)
117 +static void rev_list_push(struct negotiation_state *ns,
118 + struct commit *commit, int mark)
119 {
120 if (!(commit->object.flags & mark)) {
121 commit->object.flags |= mark;
@@ -116,19 +123,21 @@ static void rev_list_push(struct commit *commit, int mark)
123 if (parse_commit(commit))
124 return;
125
119 - prio_queue_put(&rev_list, commit);
126 + prio_queue_put(&ns->rev_list, commit);
127
128 if (!(commit->object.flags & COMMON))
122 - non_common_revs++;
129 + ns->non_common_revs++;
130 }
131 }
132
126 -static int rev_list_insert_ref(const char *refname, const struct object_id *oid)
133 +static int rev_list_insert_ref(struct negotiation_state *ns,
134 + const char *refname,
135 + const struct object_id *oid)
136 {
137 struct object *o = deref_tag(parse_object(oid), refname, 0);
138
139 if (o && o->type == OBJ_COMMIT)
131 - rev_list_push((struct commit *)o, SEEN);
140 + rev_list_push(ns, (struct commit *)o, SEEN);
141
142 return 0;
143 }
@@ -136,7 +145,7 @@ static int rev_list_insert_ref(const char *refname, const struct object_id *oid)
145 static int rev_list_insert_ref_oid(const char *refname, const struct object_id *oid,
146 int flag, void *cb_data)
147 {
139 - return rev_list_insert_ref(refname, oid);
148 + return rev_list_insert_ref(cb_data, refname, oid);
149 }
150
151 static int clear_marks(const char *refname, const struct object_id *oid,
@@ -156,7 +165,7 @@ static int clear_marks(const char *refname, const struct object_id *oid,
165 when only the server does not yet know that they are common).
166 */
167
159 -static void mark_common(struct commit *commit,
168 +static void mark_common(struct negotiation_state *ns, struct commit *commit,
169 int ancestors_only, int dont_parse)
170 {
171 if (commit != NULL && !(commit->object.flags & COMMON)) {
@@ -166,12 +175,12 @@ static void mark_common(struct commit *commit,
175 o->flags |= COMMON;
176
177 if (!(o->flags & SEEN))
169 - rev_list_push(commit, SEEN);
178 + rev_list_push(ns, commit, SEEN);
179 else {
180 struct commit_list *parents;
181
182 if (!ancestors_only && !(o->flags & POPPED))
174 - non_common_revs--;
183 + ns->non_common_revs--;
184 if (!o->parsed && !dont_parse)
185 if (parse_commit(commit))
186 return;
@@ -179,7 +188,8 @@ static void mark_common(struct commit *commit,
188 for (parents = commit->parents;
189 parents;
190 parents = parents->next)
182 - mark_common(parents->item, 0, dont_parse);
191 + mark_common(ns, parents->item, 0,
192 + dont_parse);
193 }
194 }
195 }
@@ -188,7 +198,7 @@ static void mark_common(struct commit *commit,
198 Get the next rev to send, ignoring the common.
199 */
200
191 -static const struct object_id *get_rev(void)
201 +static const struct object_id *get_rev(struct negotiation_state *ns)
202 {
203 struct commit *commit = NULL;
204
@@ -196,16 +206,16 @@ static const struct object_id *get_rev(void)
206 unsigned int mark;
207 struct commit_list *parents;
208
199 - if (rev_list.nr == 0 || non_common_revs == 0)
209 + if (ns->rev_list.nr == 0 || ns->non_common_revs == 0)
210 return NULL;
211
202 - commit = prio_queue_get(&rev_list);
212 + commit = prio_queue_get(&ns->rev_list);
213 parse_commit(commit);
214 parents = commit->parents;
215
216 commit->object.flags |= POPPED;
217 if (!(commit->object.flags & COMMON))
208 - non_common_revs--;
218 + ns->non_common_revs--;
219
220 if (commit->object.flags & COMMON) {
221 /* do not send "have", and ignore ancestors */
@@ -220,9 +230,9 @@ static const struct object_id *get_rev(void)
230
231 while (parents) {
232 if (!(parents->item->object.flags & SEEN))
223 - rev_list_push(parents->item, mark);
233 + rev_list_push(ns, parents->item, mark);
234 if (mark & COMMON)
225 - mark_common(parents->item, 1, 0);
235 + mark_common(ns, parents->item, 1, 0);
236 parents = parents->next;
237 }
238 }
@@ -296,9 +306,10 @@ static void send_request(struct fetch_pack_args *args,
306 write_or_die(fd, buf->buf, buf->len);
307 }
308
299 -static void insert_one_alternate_object(struct object *obj)
309 +static void insert_one_alternate_object(struct negotiation_state *ns,
310 + struct object *obj)
311 {
301 - rev_list_insert_ref(NULL, &obj->oid);
312 + rev_list_insert_ref(ns, NULL, &obj->oid);
313 }
314
315 #define INITIAL_FLUSH 16
@@ -321,7 +332,8 @@ static int next_flush(int stateless_rpc, int count)
332 return count;
333 }
334
324 -static int find_common(struct fetch_pack_args *args,
335 +static int find_common(struct negotiation_state *ns,
336 + struct fetch_pack_args *args,
337 int fd[2], struct object_id *result_oid,
338 struct ref *refs)
339 {
@@ -337,8 +349,8 @@ static int find_common(struct fetch_pack_args *args,
349 if (args->stateless_rpc && multi_ack == 1)
350 die(_("--stateless-rpc requires multi_ack_detailed"));
351
340 - for_each_ref(rev_list_insert_ref_oid, NULL);
341 - for_each_cached_alternate(insert_one_alternate_object);
352 + for_each_ref(rev_list_insert_ref_oid, ns);
353 + for_each_cached_alternate(ns, insert_one_alternate_object);
354
355 fetching = 0;
356 for ( ; refs ; refs = refs->next) {
@@ -456,7 +468,7 @@ static int find_common(struct fetch_pack_args *args,
468 retval = -1;
469 if (args->no_dependents)
470 goto done;
459 - while ((oid = get_rev())) {
471 + while ((oid = get_rev(ns))) {
472 packet_buf_write(&req_buf, "have %s\n", oid_to_hex(oid));
473 print_verbose(args, "have %s", oid_to_hex(oid));
474 in_vain++;
@@ -514,7 +526,7 @@ static int find_common(struct fetch_pack_args *args,
526 } else if (!args->stateless_rpc
527 || ack != ACK_common)
528 in_vain = 0;
517 - mark_common(commit, 0, 1);
529 + mark_common(ns, commit, 0, 1);
530 retval = 0;
531 got_continue = 1;
532 if (ack == ACK_ready)
@@ -704,7 +716,8 @@ static void filter_refs(struct fetch_pack_args *args,
716 *refs = newlist;
717 }
718
707 -static void mark_alternate_complete(struct object *obj)
719 +static void mark_alternate_complete(struct negotiation_state *unused,
720 + struct object *obj)
721 {
722 mark_complete(&obj->oid);
723 }
@@ -741,7 +754,8 @@ static int add_loose_objects_to_set(const struct object_id *oid,
754 * earliest commit time of the objects in refs that are commits and that we know
755 * the commit time of.
756 */
744 -static void mark_complete_and_common_ref(struct fetch_pack_args *args,
757 +static void mark_complete_and_common_ref(struct negotiation_state *ns,
758 + struct fetch_pack_args *args,
759 struct ref **refs)
760 {
761 struct ref *ref;
@@ -792,7 +806,7 @@ static void mark_complete_and_common_ref(struct fetch_pack_args *args,
806 if (!args->no_dependents) {
807 if (!args->deepen) {
808 for_each_ref(mark_complete_oid, NULL);
795 - for_each_cached_alternate(mark_alternate_complete);
809 + for_each_cached_alternate(NULL, mark_alternate_complete);
810 commit_list_sort_by_date(&complete);
811 if (cutoff)
812 mark_recent_complete_commits(args, cutoff);
@@ -810,9 +824,10 @@ static void mark_complete_and_common_ref(struct fetch_pack_args *args,
824 continue;
825
826 if (!(o->flags & SEEN)) {
813 - rev_list_push((struct commit *)o, COMMON_REF | SEEN);
827 + rev_list_push(ns, (struct commit *)o,
828 + COMMON_REF | SEEN);
829
815 - mark_common((struct commit *)o, 1, 1);
830 + mark_common(ns, (struct commit *)o, 1, 1);
831 }
832 }
833 }
@@ -995,6 +1010,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
1010 struct object_id oid;
1011 const char *agent_feature;
1012 int agent_len;
1013 + struct negotiation_state ns = { { compare_commits_by_commit_date } };
1014
1015 sort_ref_list(&ref, ref_compare_name);
1016 QSORT(sought, nr_sought, cmp_ref_by_name);
@@ -1070,13 +1086,13 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
1086 if (marked)
1087 for_each_ref(clear_marks, NULL);
1088 marked = 1;
1073 - mark_complete_and_common_ref(args, &ref);
1089 + mark_complete_and_common_ref(&ns, args, &ref);
1090 filter_refs(args, &ref, sought, nr_sought);
1091 if (everything_local(args, &ref)) {
1092 packet_flush(fd[1]);
1093 goto all_done;
1094 }
1079 - if (find_common(args, fd, &oid, ref) < 0)
1095 + if (find_common(&ns, args, fd, &oid, ref) < 0)
1096 if (!args->keep_pack)
1097 /* When cloning, it is not unusual to have
1098 * no common commit.
@@ -1096,7 +1112,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
1112 die(_("git fetch-pack: fetch failed."));
1113
1114 all_done:
1099 - clear_prio_queue(&rev_list);
1115 + clear_prio_queue(&ns.rev_list);
1116 return ref;
1117 }
1118
@@ -1158,13 +1174,14 @@ static void add_common(struct strbuf *req_buf, struct oidset *common)
1174 }
1175 }
1176
1161 -static int add_haves(struct strbuf *req_buf, int *haves_to_send, int *in_vain)
1177 +static int add_haves(struct negotiation_state *ns, struct strbuf *req_buf,
1178 + int *haves_to_send, int *in_vain)
1179 {
1180 int ret = 0;
1181 int haves_added = 0;
1182 const struct object_id *oid;
1183
1167 - while ((oid = get_rev())) {
1184 + while ((oid = get_rev(ns))) {
1185 packet_buf_write(req_buf, "have %s\n", oid_to_hex(oid));
1186 if (++haves_added >= *haves_to_send)
1187 break;
@@ -1183,7 +1200,8 @@ static int add_haves(struct strbuf *req_buf, int *haves_to_send, int *in_vain)
1200 return ret;
1201 }
1202
1186 -static int send_fetch_request(int fd_out, const struct fetch_pack_args *args,
1203 +static int send_fetch_request(struct negotiation_state *ns, int fd_out,
1204 + const struct fetch_pack_args *args,
1205 const struct ref *wants, struct oidset *common,
1206 int *haves_to_send, int *in_vain)
1207 {
@@ -1239,7 +1257,7 @@ static int send_fetch_request(int fd_out, const struct fetch_pack_args *args,
1257 add_common(&req_buf, common);
1258
1259 /* Add initial haves */
1242 - ret = add_haves(&req_buf, haves_to_send, in_vain);
1260 + ret = add_haves(ns, &req_buf, haves_to_send, in_vain);
1261 }
1262
1263 /* Send request */
@@ -1276,7 +1294,9 @@ static int process_section_header(struct packet_reader *reader,
1294 return ret;
1295 }
1296
1279 -static int process_acks(struct packet_reader *reader, struct oidset *common)
1297 +static int process_acks(struct negotiation_state *ns,
1298 + struct packet_reader *reader,
1299 + struct oidset *common)
1300 {
1301 /* received */
1302 int received_ready = 0;
@@ -1295,7 +1315,7 @@ static int process_acks(struct packet_reader *reader, struct oidset *common)
1315 struct commit *commit;
1316 oidset_insert(common, &oid);
1317 commit = lookup_commit(&oid);
1298 - mark_common(commit, 0, 1);
1318 + mark_common(ns, commit, 0, 1);
1319 }
1320 continue;
1321 }
@@ -1373,6 +1393,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1393 struct packet_reader reader;
1394 int in_vain = 0;
1395 int haves_to_send = INITIAL_FLUSH;
1396 + struct negotiation_state ns = { { compare_commits_by_commit_date } };
1397 packet_reader_init(&reader, fd[0], NULL, 0,
1398 PACKET_READ_CHOMP_NEWLINE);
1399
@@ -1393,18 +1414,19 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1414 marked = 1;
1415
1416 /* Filter 'ref' by 'sought' and those that aren't local */
1396 - mark_complete_and_common_ref(args, &ref);
1417 + mark_complete_and_common_ref(&ns, args, &ref);
1418 filter_refs(args, &ref, sought, nr_sought);
1419 if (everything_local(args, &ref))
1420 state = FETCH_DONE;
1421 else
1422 state = FETCH_SEND_REQUEST;
1423
1403 - for_each_ref(rev_list_insert_ref_oid, NULL);
1404 - for_each_cached_alternate(insert_one_alternate_object);
1424 + for_each_ref(rev_list_insert_ref_oid, &ns);
1425 + for_each_cached_alternate(&ns,
1426 + insert_one_alternate_object);
1427 break;
1428 case FETCH_SEND_REQUEST:
1407 - if (send_fetch_request(fd[1], args, ref, &common,
1429 + if (send_fetch_request(&ns, fd[1], args, ref, &common,
1430 &haves_to_send, &in_vain))
1431 state = FETCH_GET_PACK;
1432 else
@@ -1412,7 +1434,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1434 break;
1435 case FETCH_PROCESS_ACKS:
1436 /* Process ACKs/NAKs */
1415 - switch (process_acks(&reader, &common)) {
1437 + switch (process_acks(&ns, &reader, &common)) {
1438 case 2:
1439 state = FETCH_GET_PACK;
1440 break;
@@ -1441,7 +1463,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1463 }
1464 }
1465
1444 - clear_prio_queue(&rev_list);
1466 + clear_prio_queue(&ns.rev_list);
1467 oidset_clear(&common);
1468 return ref;
1469 }