Re: [PATCH v2 1/3] promisor-remote: refactor to get rid of 'struct strvec'
- From
Christian Couder <christian.couder@gmail.com>
- Date
- May 19, 2025, 14:10 UTC
- Message-ID
- <CAP8UFD0c+LfCoHzvMyGYkmNmFd4PApEgmt65-TzLBvdap3LvdQ@mail.gmail.com>
- In-Reply-To
- <aBsZAKmaA_uGPgk2@pks.im>
On Wed, May 7, 2025 at 10:25 AM Patrick Steinhardt <ps@pks.im> wrote:
> > On Tue, Apr 29, 2025 at 04:52:41PM +0200, Christian Couder wrote:
Show 26 quoted lines
> > +/*
> > + * Linked list for promisor remotes involved in the "promisor-remote"
> > + * protocol capability.
> > + *
> > + * 'fields' contains a defined set of field name/value pairs for
> > + * each promisor remote. Field names are stored in the 'string'
> > + * member, and values in the 'util' member.
> > + *
> > + * Currently supported field names:
> > + * - "name": The name of the promisor remote.
> > + * - "url": The URL of the promisor remote.
> > + *
> > + * Except for "name", each "<field_name>/<field_value>" pair should
> > + * correspond to a "remote.<name>.<field_name>" config variable set to
> > + * <field_value> where "<name>" is a promisor remote name.
> > + *
> > + * 'fields' should not be sorted, as we will rely on the order we put
> > + * things into it. So, for example, 'string_list_append()' should be
> > + * used instead of 'string_list_insert()'.
> > + */
> > +struct promisor_info {
> > + struct promisor_info *next;
> > + struct string_list fields;
>
> Now that we have a restricted set of accepted fields, wouldn't it be
> easier to store those as individual members of this struct directly?I have done so in the v3. The struct now looks like this at the end of the series:
struct promisor_info {
struct promisor_info *next;
const char *name;
const char *url;
const char *filter;
const char *token;
};Show 30 quoted lines
> [snip]
> > /*
> > - * Find first index of 'nicks' where there is 'nick'. 'nick' is
> > - * compared case sensitively to the strings in 'nicks'. If not found
> > - * 'nicks->nr' is returned.
> > + * Find first element of 'p' where the 'name' field is 'nick'. 'nick'
> > + * is compared case sensitively to the strings in 'p'. If not found
> > + * NULL is returned.
> > */
> > -static size_t remote_nick_find(struct strvec *nicks, const char *nick)
> > +static struct promisor_info *remote_nick_find(struct promisor_info *p, const char *nick)
> > {
> > - for (size_t i = 0; i < nicks->nr; i++)
> > - if (!strcmp(nicks->v[i], nick))
> > - return i;
> > - return nicks->nr;
> > + for (; p; p = p->next) {
> > + if (strcmp(p->fields.items[0].string, "name"))
> > + BUG("First field of promisor info should be 'name', but was '%s'.",
> > + p->fields.items[0].string);
> > + if (!strcmp(p->fields.items[0].util, nick))
> > + return p;
> > + }
> > + return NULL;
> > }
> >
> > enum accept_promisor {
>
> If so, we could also simplify code like this because we wouldn't have to
> assume any indices anymore.Yeah, it simplifies things, but on the other hand in some places the fields cannot be handled in a generic way, so we have things like:
if (!strcmp(elem, promisor_field_name))
info->name = value;
else if (!strcmp(elem, promisor_field_url))
info->url = value;
else if (!strcasecmp(elem, promisor_field_filter))
info->filter = value;
else if (!strcasecmp(elem, promisor_field_token))
info->token = value;Anyway I think that it's not too bad.