Skip to content

Commit 9fec7b2

Browse files
pks-tgitster
authored andcommitted
connected: refactor iterator to return next object ID directly
The object ID iterator used by the connectivity checks returns the next object ID via an out-parameter and then uses a return code to indicate whether an item was found. This is a bit roundabout: instead of a separate error code, we can just return the next object ID directly and use `NULL` pointers as indicator that the iterator got no items left. Furthermore, this avoids a copy of the object ID. Refactor the iterator and all its implementations to return object IDs directly. This brings a tiny performance improvement when doing a mirror-fetch of a repository with about 2.3M refs: Benchmark #1: 328dc58b49919c43897240f2eabfa30be2ce32a4~: git-fetch Time (mean ± σ): 30.110 s ± 0.148 s [User: 27.161 s, System: 5.075 s] Range (min … max): 29.934 s … 30.406 s 10 runs Benchmark #2: 328dc58b49919c43897240f2eabfa30be2ce32a4: git-fetch Time (mean ± σ): 29.899 s ± 0.109 s [User: 26.916 s, System: 5.104 s] Range (min … max): 29.696 s … 29.996 s 10 runs Summary '328dc58b49919c43897240f2eabfa30be2ce32a4: git-fetch' ran 1.01 ± 0.01 times faster than '328dc58b49919c43897240f2eabfa30be2ce32a4~: git-fetch' While this 1% speedup could be labelled as statistically insignificant, the speedup is consistent on my machine. Furthermore, this is an end to end test, so it is expected that the improvement in the connectivity check itself is more significant. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 47c6100 commit 9fec7b2

File tree

6 files changed

+25
-31
lines changed

6 files changed

+25
-31
lines changed

builtin/clone.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ static void write_followtags(const struct ref *refs, const char *msg)
657657
}
658658
}
659659

660-
static int iterate_ref_map(void *cb_data, struct object_id *oid)
660+
static const struct object_id *iterate_ref_map(void *cb_data)
661661
{
662662
struct ref **rm = cb_data;
663663
struct ref *ref = *rm;
@@ -668,13 +668,11 @@ static int iterate_ref_map(void *cb_data, struct object_id *oid)
668668
*/
669669
while (ref && !ref->peer_ref)
670670
ref = ref->next;
671-
/* Returning -1 notes "end of list" to the caller. */
672671
if (!ref)
673-
return -1;
672+
return NULL;
674673

675-
oidcpy(oid, &ref->old_oid);
676674
*rm = ref->next;
677-
return 0;
675+
return &ref->old_oid;
678676
}
679677

680678
static void update_remote_refs(const struct ref *refs,

builtin/fetch.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -962,18 +962,17 @@ static int update_local_ref(struct ref *ref,
962962
}
963963
}
964964

965-
static int iterate_ref_map(void *cb_data, struct object_id *oid)
965+
static const struct object_id *iterate_ref_map(void *cb_data)
966966
{
967967
struct ref **rm = cb_data;
968968
struct ref *ref = *rm;
969969

970970
while (ref && ref->status == REF_STATUS_REJECT_SHALLOW)
971971
ref = ref->next;
972972
if (!ref)
973-
return -1; /* end of the list */
973+
return NULL;
974974
*rm = ref->next;
975-
oidcpy(oid, &ref->old_oid);
976-
return 0;
975+
return &ref->old_oid;
977976
}
978977

979978
struct fetch_head {

builtin/receive-pack.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,7 +1306,7 @@ static void refuse_unconfigured_deny_delete_current(void)
13061306
rp_error("%s", _(refuse_unconfigured_deny_delete_current_msg));
13071307
}
13081308

1309-
static int command_singleton_iterator(void *cb_data, struct object_id *oid);
1309+
static const struct object_id *command_singleton_iterator(void *cb_data);
13101310
static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
13111311
{
13121312
struct shallow_lock shallow_lock = SHALLOW_LOCK_INIT;
@@ -1731,16 +1731,15 @@ static void check_aliased_updates(struct command *commands)
17311731
string_list_clear(&ref_list, 0);
17321732
}
17331733

1734-
static int command_singleton_iterator(void *cb_data, struct object_id *oid)
1734+
static const struct object_id *command_singleton_iterator(void *cb_data)
17351735
{
17361736
struct command **cmd_list = cb_data;
17371737
struct command *cmd = *cmd_list;
17381738

17391739
if (!cmd || is_null_oid(&cmd->new_oid))
1740-
return -1; /* end of list */
1740+
return NULL;
17411741
*cmd_list = NULL; /* this returns only one */
1742-
oidcpy(oid, &cmd->new_oid);
1743-
return 0;
1742+
return &cmd->new_oid;
17441743
}
17451744

17461745
static void set_connectivity_errors(struct command *commands,
@@ -1770,7 +1769,7 @@ struct iterate_data {
17701769
struct shallow_info *si;
17711770
};
17721771

1773-
static int iterate_receive_command_list(void *cb_data, struct object_id *oid)
1772+
static const struct object_id *iterate_receive_command_list(void *cb_data)
17741773
{
17751774
struct iterate_data *data = cb_data;
17761775
struct command **cmd_list = &data->cmds;
@@ -1781,13 +1780,11 @@ static int iterate_receive_command_list(void *cb_data, struct object_id *oid)
17811780
/* to be checked in update_shallow_ref() */
17821781
continue;
17831782
if (!is_null_oid(&cmd->new_oid) && !cmd->skip_update) {
1784-
oidcpy(oid, &cmd->new_oid);
17851783
*cmd_list = cmd->next;
1786-
return 0;
1784+
return &cmd->new_oid;
17871785
}
17881786
}
1789-
*cmd_list = NULL;
1790-
return -1; /* end of list */
1787+
return NULL;
17911788
}
17921789

17931790
static void reject_updates_to_hidden(struct command *commands)

connected.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
2424
struct child_process rev_list = CHILD_PROCESS_INIT;
2525
FILE *rev_list_in;
2626
struct check_connected_options defaults = CHECK_CONNECTED_INIT;
27-
struct object_id oid;
27+
const struct object_id *oid;
2828
int err = 0;
2929
struct packed_git *new_pack = NULL;
3030
struct transport *transport;
@@ -34,7 +34,8 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
3434
opt = &defaults;
3535
transport = opt->transport;
3636

37-
if (fn(cb_data, &oid)) {
37+
oid = fn(cb_data);
38+
if (!oid) {
3839
if (opt->err_fd)
3940
close(opt->err_fd);
4041
return err;
@@ -73,7 +74,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
7374
for (p = get_all_packs(the_repository); p; p = p->next) {
7475
if (!p->pack_promisor)
7576
continue;
76-
if (find_pack_entry_one(oid.hash, p))
77+
if (find_pack_entry_one(oid->hash, p))
7778
goto promisor_pack_found;
7879
}
7980
/*
@@ -83,7 +84,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
8384
goto no_promisor_pack_found;
8485
promisor_pack_found:
8586
;
86-
} while (!fn(cb_data, &oid));
87+
} while ((oid = fn(cb_data)) != NULL);
8788
return 0;
8889
}
8990

@@ -132,12 +133,12 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
132133
* are sure the ref is good and not sending it to
133134
* rev-list for verification.
134135
*/
135-
if (new_pack && find_pack_entry_one(oid.hash, new_pack))
136+
if (new_pack && find_pack_entry_one(oid->hash, new_pack))
136137
continue;
137138

138-
if (fprintf(rev_list_in, "%s\n", oid_to_hex(&oid)) < 0)
139+
if (fprintf(rev_list_in, "%s\n", oid_to_hex(oid)) < 0)
139140
break;
140-
} while (!fn(cb_data, &oid));
141+
} while ((oid = fn(cb_data)) != NULL);
141142

142143
if (ferror(rev_list_in) || fflush(rev_list_in)) {
143144
if (errno != EPIPE && errno != EINVAL)

connected.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ struct transport;
99
* When called after returning the name for the last object, return -1
1010
* to signal EOF, otherwise return 0.
1111
*/
12-
typedef int (*oid_iterate_fn)(void *, struct object_id *oid);
12+
typedef const struct object_id *(*oid_iterate_fn)(void *);
1313

1414
/*
1515
* Named-arguments struct for check_connected. All arguments are

fetch-pack.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,16 +1912,15 @@ static void update_shallow(struct fetch_pack_args *args,
19121912
oid_array_clear(&ref);
19131913
}
19141914

1915-
static int iterate_ref_map(void *cb_data, struct object_id *oid)
1915+
static const struct object_id *iterate_ref_map(void *cb_data)
19161916
{
19171917
struct ref **rm = cb_data;
19181918
struct ref *ref = *rm;
19191919

19201920
if (!ref)
1921-
return -1; /* end of the list */
1921+
return NULL;
19221922
*rm = ref->next;
1923-
oidcpy(oid, &ref->old_oid);
1924-
return 0;
1923+
return &ref->old_oid;
19251924
}
19261925

19271926
struct ref *fetch_pack(struct fetch_pack_args *args,

0 commit comments

Comments
 (0)