Skip to content

Commit 6ac8bf8

Browse files
committed
promisor-remote: keep advertised filter in memory
Currently, advertised filters are only kept in memory temporarily during parsing, or persisted to disk if `promisor.storeFields` contains 'partialCloneFilter'. In a following commit though, we will add a `--filter=auto` option. This option will enable the client to use the filters that the server is suggesting for the promisor remotes the client accepts. To use them even if `promisor.storeFields` is not configured, these filters should be stored somewhere for the current session. Let's add an `advertised_filter` field to `struct promisor_remote` for that purpose. To ensure that the filters are available in all cases, filter_promisor_remote() captures them into a temporary list and applies them to the `promisor_remote` structs after the potential configuration reload. Then the accepted remotes are marked as `accepted` in the repository state. This ensures that subsequent calls to look up accepted remotes (like in the filter construction below) actually find them. In a following commit, we will add a `--filter=auto` option that will enable a client to use the filters suggested by the server for the promisor remotes the client accepted. To enable the client to construct a filter spec based on these filters, let's add a `promisor_remote_construct_filter(repo)` function. This function: - iterates over all accepted promisor remotes in the repository, - collects the filters advertised for them (using `advertised_filter` which a previous commit added to `struct promisor_remote`), and - generates a single filter spec for them (using the `list_objects_filter_combine()` function added by a previous commit). Signed-off-by: Christian Couder <[email protected]>
1 parent 1b88355 commit 6ac8bf8

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

promisor-remote.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ void promisor_remote_clear(struct promisor_remote_config *config)
193193
while (config->promisors) {
194194
struct promisor_remote *r = config->promisors;
195195
free(r->partial_clone_filter);
196+
free(r->advertised_filter);
196197
config->promisors = config->promisors->next;
197198
free(r);
198199
}
@@ -837,6 +838,7 @@ static void filter_promisor_remote(struct repository *repo,
837838
struct store_info *store_info = NULL;
838839
struct string_list_item *item;
839840
bool reload_config = false;
841+
struct string_list captured_filters = STRING_LIST_INIT_DUP;
840842

841843
if (!repo_config_get_string_tmp(the_repository, "promisor.acceptfromserver", &accept_str)) {
842844
if (!*accept_str || !strcasecmp("None", accept_str))
@@ -879,6 +881,13 @@ static void filter_promisor_remote(struct repository *repo,
879881
reload_config = true;
880882

881883
strvec_push(accepted, advertised->name);
884+
885+
/* Capture advertised filters for accepted remotes */
886+
if (advertised->filter) {
887+
struct string_list_item *i;
888+
i = string_list_append(&captured_filters, advertised->name);
889+
i->util = xstrdup(advertised->filter);
890+
}
882891
}
883892

884893
promisor_info_free(advertised);
@@ -890,6 +899,25 @@ static void filter_promisor_remote(struct repository *repo,
890899

891900
if (reload_config)
892901
repo_promisor_remote_reinit(repo);
902+
903+
/* Apply captured filters to the stable repo state */
904+
for_each_string_list_item(item, &captured_filters) {
905+
struct promisor_remote *r = repo_promisor_remote_find(repo, item->string);
906+
if (r) {
907+
free(r->advertised_filter);
908+
r->advertised_filter = item->util;
909+
item->util = NULL;
910+
}
911+
}
912+
913+
string_list_clear(&captured_filters, 1);
914+
915+
/* Mark the remotes as accepted in the repository state */
916+
for (size_t i = 0; i < accepted->nr; i++) {
917+
struct promisor_remote *r = repo_promisor_remote_find(repo, accepted->v[i]);
918+
if (r)
919+
r->accepted = 1;
920+
}
893921
}
894922

895923
char *promisor_remote_reply(const char *info)
@@ -935,3 +963,23 @@ void mark_promisor_remotes_as_accepted(struct repository *r, const char *remotes
935963

936964
string_list_clear(&accepted_remotes, 0);
937965
}
966+
967+
char *promisor_remote_construct_filter(struct repository *repo)
968+
{
969+
struct string_list advertised_filters = STRING_LIST_INIT_NODUP;
970+
struct promisor_remote *r;
971+
char *result;
972+
973+
promisor_remote_init(repo);
974+
975+
for (r = repo->promisor_remote_config->promisors; r; r = r->next) {
976+
if (r->accepted && r->advertised_filter)
977+
string_list_append(&advertised_filters, r->advertised_filter);
978+
}
979+
980+
result = list_objects_filter_combine(&advertised_filters);
981+
982+
string_list_clear(&advertised_filters, 0);
983+
984+
return result;
985+
}

promisor-remote.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct object_id;
1515
struct promisor_remote {
1616
struct promisor_remote *next;
1717
char *partial_clone_filter;
18+
char *advertised_filter;
1819
unsigned int accepted : 1;
1920
const char name[FLEX_ARRAY];
2021
};
@@ -67,4 +68,9 @@ void mark_promisor_remotes_as_accepted(struct repository *repo, const char *remo
6768
*/
6869
int repo_has_accepted_promisor_remote(struct repository *r);
6970

71+
/*
72+
* Use the filters from the accepted remotes to create a filter.
73+
*/
74+
char *promisor_remote_construct_filter(struct repository *repo);
75+
7076
#endif /* PROMISOR_REMOTE_H */

0 commit comments

Comments
 (0)