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
}