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