On Thu, Aug 9, 2018 at 12:39 AM Martin Ågren <martin.ag...@gmail.com> wrote:
>
> On 9 August 2018 at 00:17, Stefan Beller <sbel...@google.com> wrote:
> > +int oid_array_remove_if(struct oid_array *array,
> > +                       for_each_oid_fn fn,
> > +                       void *data)
> > +{
> > +       int i, j;
> > +       char *to_remove = xcalloc(array->nr, sizeof(char));
>
> Do you really need this scratch space?

I don't think so, when we reorder the items while iterating over them.

I though reordering them later would be easier, but I am not sure anymore.

>
> > +       /* No oid_array_sort() here! See the api-oid-array.txt docs! */
> > +
> > +       for (i = 0; i < array->nr; i++) {
> > +               int ret = fn(array->oid + i, data);
> > +               if (ret)
> > +                       to_remove[i] = 1;
> > +       }
> > +
> > +       i = 0, j = 0;
> > +       while (i < array->nr && j < array->nr) {
> > +               while (i < array->nr && !to_remove[i])
> > +                       i++;
> > +               /* i at first marked for deletion or out */
> > +               if (j < i)
> > +                       j = i;
> > +               while (j < array->nr && to_remove[j])
> > +                       j++;
> > +               /* j > i; j at first valid after first deletion range or 
> > out */
> > +               if (i < array->nr && j < array->nr)
> > +                       oidcpy(&array->oid[i], &array->oid[j]);
> > +               else if (i >= array->nr)
> > +                       assert(j >= array->nr);
> > +                       /* no pruning happened, keep original array->nr */
> > +               else if (j >= array->nr)
> > +                       array->nr = i;
> > +       }
> > +
> > +       free(to_remove);
> > +
> > +       return 0;
> > +}
>
> I can't entirely follow this index-fiddling, but then I haven't had my
> morning coffee yet, so please forgive me if this is nonsense. Would it
> suffice to let i point out where to place items (starting at the first
> item not to keep) and j where to take them from (i.e., the items to
> keep, after the initial run)?

I thought this is what happens, just after the actual loop of calls.

> > +int oid_array_remove_if(struct oid_array *array,
> > +                       for_each_oid_fn fn,
> > +                       void *data);
>
> Maybe some documentation here, but this seems to be following suit. ;-)

Worth mentioning: the order is kept stable. (c.f. shrink_potential_moved_blocks
in diff.c which also "compacts an array", but without stable order).

Thanks for the review. I'll try to rewrite this to be more legible.

Thanks,
Stefan

Reply via email to