odb/source: make `for_each_object()` function pluggable

Introduce a new callback function in `struct odb_source` to make the function pluggable. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Mar 5, 2026 at 15:19 UTC fdefdc2e6979e9e8cb28b34c458f42b44f217bf0
4 files changed +89 -23
odb.c
+1 -11
@@ -984,20 +984,10 @@ int odb_for_each_object(struct object_database *odb,
984
985 odb_prepare_alternates(odb);
986 for (struct odb_source *source = odb->sources; source; source = source->next) {
987 - struct odb_source_files *files = odb_source_files_downcast(source);
988 -
987 if (flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY && !source->local)
988 continue;
989
992 - if (!(flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY)) {
993 - ret = odb_source_loose_for_each_object(source, request,
994 - cb, cb_data, flags);
995 - if (ret)
996 - return ret;
997 - }
998 -
999 - ret = packfile_store_for_each_object(files->packed, request,
1000 - cb, cb_data, flags);
990 + ret = odb_source_for_each_object(source, request, cb, cb_data, flags);
991 if (ret)
992 return ret;
993 }
odb.h
-12
@@ -432,18 +432,6 @@ enum odb_for_each_object_flags {
432 ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS = (1<<4),
433 };
434
435 -/*
436 - * A callback function that can be used to iterate through objects. If given,
437 - * the optional `oi` parameter will be populated the same as if you would call
438 - * `odb_read_object_info()`.
439 - *
440 - * Returning a non-zero error code will cause iteration to abort. The error
441 - * code will be propagated.
442 - */
443 -typedef int (*odb_for_each_object_cb)(const struct object_id *oid,
444 - struct object_info *oi,
445 - void *cb_data);
446 -
435 /*
436 * Iterate through all objects contained in the object database. Note that
437 * objects may be iterated over multiple times in case they are either stored
odb/source-files.c
+23
@@ -66,6 +66,28 @@ static int odb_source_files_read_object_stream(struct odb_read_stream **out,
66 return -1;
67 }
68
69 +static int odb_source_files_for_each_object(struct odb_source *source,
70 + const struct object_info *request,
71 + odb_for_each_object_cb cb,
72 + void *cb_data,
73 + unsigned flags)
74 +{
75 + struct odb_source_files *files = odb_source_files_downcast(source);
76 + int ret;
77 +
78 + if (!(flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY)) {
79 + ret = odb_source_loose_for_each_object(source, request, cb, cb_data, flags);
80 + if (ret)
81 + return ret;
82 + }
83 +
84 + ret = packfile_store_for_each_object(files->packed, request, cb, cb_data, flags);
85 + if (ret)
86 + return ret;
87 +
88 + return 0;
89 +}
90 +
91 struct odb_source_files *odb_source_files_new(struct object_database *odb,
92 const char *path,
93 bool local)
@@ -82,6 +104,7 @@ struct odb_source_files *odb_source_files_new(struct object_database *odb,
104 files->base.reprepare = odb_source_files_reprepare;
105 files->base.read_object_info = odb_source_files_read_object_info;
106 files->base.read_object_stream = odb_source_files_read_object_stream;
107 + files->base.for_each_object = odb_source_files_for_each_object;
108
109 /*
110 * Ideally, we would only ever store absolute paths in the source. This
odb/source.h
+65
@@ -52,6 +52,18 @@ struct object_id;
52 struct object_info;
53 struct odb_read_stream;
54
55 +/*
56 + * A callback function that can be used to iterate through objects. If given,
57 + * the optional `oi` parameter will be populated the same as if you would call
58 + * `odb_read_object_info()`.
59 + *
60 + * Returning a non-zero error code will cause iteration to abort. The error
61 + * code will be propagated.
62 + */
63 +typedef int (*odb_for_each_object_cb)(const struct object_id *oid,
64 + struct object_info *oi,
65 + void *cb_data);
66 +
67 /*
68 * The source is the part of the object database that stores the actual
69 * objects. It thus encapsulates the logic to read and write the specific
@@ -150,6 +162,30 @@ struct odb_source {
162 int (*read_object_stream)(struct odb_read_stream **out,
163 struct odb_source *source,
164 const struct object_id *oid);
165 +
166 + /*
167 + * This callback is expected to iterate over all objects stored in this
168 + * source and invoke the callback function for each of them. It is
169 + * valid to yield the same object multiple time. A non-zero exit code
170 + * from the object callback shall abort iteration.
171 + *
172 + * The optional `request` structure should serve as a template for
173 + * looking up object info for every individual iterated object. It
174 + * should not be modified directly and should instead be copied into a
175 + * separate `struct object_info` that gets passed to the callback. If
176 + * the caller passes a `NULL` pointer then the object itself shall not
177 + * be read.
178 + *
179 + * The callback is expected to return a negative error code in case the
180 + * iteration has failed to read all objects, 0 otherwise. When the
181 + * callback function returns a non-zero error code then that error code
182 + * should be returned.
183 + */
184 + int (*for_each_object)(struct odb_source *source,
185 + const struct object_info *request,
186 + odb_for_each_object_cb cb,
187 + void *cb_data,
188 + unsigned flags);
189 };
190
191 /*
@@ -232,4 +268,33 @@ static inline int odb_source_read_object_stream(struct odb_read_stream **out,
268 return source->read_object_stream(out, source, oid);
269 }
270
271 +/*
272 + * Iterate through all objects contained in the given source and invoke the
273 + * callback function for each of them. Returning a non-zero code from the
274 + * callback function aborts iteration. There is no guarantee that objects
275 + * are only iterated over once.
276 + *
277 + * The optional `request` structure serves as a template for retrieving the
278 + * object info for each indvidual iterated object and will be populated as if
279 + * `odb_source_read_object_info()` was called on the object. It will not be
280 + * modified, the callback will instead be invoked with a separate `struct
281 + * object_info` for every object. Object info will not be read when passing a
282 + * `NULL` pointer.
283 + *
284 + * The flags is a bitfield of `ODB_FOR_EACH_OBJECT_*` flags. Not all flags may
285 + * apply to a specific backend, so whether or not they are honored is defined
286 + * by the implementation.
287 + *
288 + * Returns 0 when all objects have been iterated over, a negative error code in
289 + * case iteration has failed, or a non-zero value returned from the callback.
290 + */
291 +static inline int odb_source_for_each_object(struct odb_source *source,
292 + const struct object_info *request,
293 + odb_for_each_object_cb cb,
294 + void *cb_data,
295 + unsigned flags)
296 +{
297 + return source->for_each_object(source, request, cb, cb_data, flags);
298 +}
299 +
300 #endif