Skip to content

Commit fdefdc2

Browse files
pks-tgitster
authored andcommitted
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>
1 parent 1f3fd68 commit fdefdc2

4 files changed

Lines changed: 89 additions & 23 deletions

File tree

odb.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -984,20 +984,10 @@ int odb_for_each_object(struct object_database *odb,
984984

985985
odb_prepare_alternates(odb);
986986
for (struct odb_source *source = odb->sources; source; source = source->next) {
987-
struct odb_source_files *files = odb_source_files_downcast(source);
988-
989987
if (flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY && !source->local)
990988
continue;
991989

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);
1001991
if (ret)
1002992
return ret;
1003993
}

odb.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -432,18 +432,6 @@ enum odb_for_each_object_flags {
432432
ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS = (1<<4),
433433
};
434434

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-
447435
/*
448436
* Iterate through all objects contained in the object database. Note that
449437
* objects may be iterated over multiple times in case they are either stored

odb/source-files.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,28 @@ static int odb_source_files_read_object_stream(struct odb_read_stream **out,
6666
return -1;
6767
}
6868

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+
6991
struct odb_source_files *odb_source_files_new(struct object_database *odb,
7092
const char *path,
7193
bool local)
@@ -82,6 +104,7 @@ struct odb_source_files *odb_source_files_new(struct object_database *odb,
82104
files->base.reprepare = odb_source_files_reprepare;
83105
files->base.read_object_info = odb_source_files_read_object_info;
84106
files->base.read_object_stream = odb_source_files_read_object_stream;
107+
files->base.for_each_object = odb_source_files_for_each_object;
85108

86109
/*
87110
* Ideally, we would only ever store absolute paths in the source. This

odb/source.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,18 @@ struct object_id;
5252
struct object_info;
5353
struct odb_read_stream;
5454

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+
5567
/*
5668
* The source is the part of the object database that stores the actual
5769
* objects. It thus encapsulates the logic to read and write the specific
@@ -150,6 +162,30 @@ struct odb_source {
150162
int (*read_object_stream)(struct odb_read_stream **out,
151163
struct odb_source *source,
152164
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);
153189
};
154190

155191
/*
@@ -232,4 +268,33 @@ static inline int odb_source_read_object_stream(struct odb_read_stream **out,
232268
return source->read_object_stream(out, source, oid);
233269
}
234270

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+
235300
#endif

0 commit comments

Comments
 (0)