Re: [PATCH 11/17] odb/source: make `for_each_object()` function pluggable
- From
Karthik Nayak <karthik.188@gmail.com>
- Date
- Mar 5, 2026, 13:07 UTC
- Message-ID
- <CAOLa=ZS9ODS1EdZMDW7aRjp+9yk1E0mW15wabPNzTmBxOtwOgQ@mail.gmail.com>
- In-Reply-To
- <20260223-b4-pks-odb-source-pluggable-v1-11-253bac1db598@pks.im>
[snip]
Show 30 quoted lines
> diff --git a/odb/source.h b/odb/source.h
> index edb425fdef..35aa78e140 100644
> --- a/odb/source.h
> +++ b/odb/source.h
> @@ -53,6 +53,18 @@ struct object_id;
> struct object_info;
> struct odb_read_stream;
>
> +/*
> + * A callback function that can be used to iterate through objects. If given,
> + * the optional `oi` parameter will be populated the same as if you would call
> + * `odb_read_object_info()`.
> + *
> + * Returning a non-zero error code will cause iteration to abort. The error
> + * code will be propagated.
> + */
> +typedef int (*odb_for_each_object_cb)(const struct object_id *oid,
> + struct object_info *oi,
> + void *cb_data);
> +
> /*
> * The source is the part of the object database that stores the actual
> * objects. It thus encapsulates the logic to read and write the specific
> @@ -151,6 +163,27 @@ struct odb_source {
> int (*read_object_stream)(struct odb_read_stream **out,
> struct odb_source *source,
> const struct object_id *oid);
> +
> + /*
> + * This callback is expected to iterate over all objects stored in thisThis isn't a callback though, this is a function which calls the callback, right?
Show 8 quoted lines
> + * source and invoke the callback function for each of them. It is > + * valid to yield the same object multiple time. A non-zero exit code > + * from the object callback shall abort iteration. > + * > + * The optional `oi` structure shall be populated similar to how an individual > + * call to `odb_source_read_object_info()` would have behaved. If the caller > + * passes a `NULL` pointer then the object itself shall not be read. > + *
Nit: here and below, we talk about the `oi` structure, but that's in the callback function, maybe we should clarify that.
Show 47 quoted lines
> + * The callback is expected to return a negative error code in case the
> + * iteration has failed to read all objects, 0 otherwise. When the
> + * callback function returns a non-zero error code then that error code
> + * should be returned.
> + */
> + int (*for_each_object)(struct odb_source *source,
> + const struct object_info *request,
> + odb_for_each_object_cb cb,
> + void *cb_data,
> + unsigned flags);
> };
>
> /*
> @@ -233,4 +266,30 @@ static inline int odb_source_read_object_stream(struct odb_read_stream **out,
> return source->read_object_stream(out, source, oid);
> }
>
> +/*
> + * Iterate through all objects contained in the given source and invoke the
> + * callback function for each of them. Returning a non-zero code from the
> + * callback function aborts iteration. There is no guarantee that objects
> + * are only iterated over once.
> + *
> + * The optional `oi` structure shall be populated similar to how an individual
> + * call to `odb_source_read_object_info()` would have behaved. If the caller
> + * passes a `NULL` pointer then the object itself shall not be read.
> + *
> + * The flags is a bitfield of `ODB_FOR_EACH_OBJECT_*` flags. Not all flags may
> + * apply to a specific backend, so whether or not they are honored is defined
> + * by the implementation.
> + *
> + * Returns 0 when all objects have been iterated over, a negative error code in
> + * case iteration has failed, or a non-zero value returned from the callback.
> + */
> +static inline int odb_source_for_each_object(struct odb_source *source,
> + const struct object_info *request,
> + odb_for_each_object_cb cb,
> + void *cb_data,
> + unsigned flags)
> +{
> + return source->for_each_object(source, request, cb, cb_data, flags);
> +}
> +
> #endif
>
> --
> 2.53.0.536.g309c995771.dirty