Skip to content

Commit a8303b1

Browse files
committed
odb: use odb_source_files_try() in source-chain iterations
Convert all source-chain iteration sites that access files-specific internals (pack store, loose cache, MIDX) to use odb_source_files_try() instead of odb_source_files_downcast(). These loops iterate the full source chain, which may include alternates. When a non-files backend is added to the chain (as an alternate or additional source), these sites must skip it rather than abort. The _try() helper returns NULL for non-files sources, and each site checks for NULL before accessing files-specific members. Call sites that access odb->sources directly (the primary source, which is always a files backend) or that are inside files-backend vtable callbacks continue to use odb_source_files_downcast() with its BUG() safety guarantee. Sites converted (22 across 11 files): - loose.c: loose object map loading and oid lookup - midx.c: multi-pack-index access and cleanup - object-file.c: loose cache and reprepare - object-name.c: short object filename search - packfile.c: window/fd management, pack entry lookup - packfile.h: repo_for_each_pack iterator macros - commit-graph.c: packed object enumeration - builtin/cat-file.c: batch object iteration - builtin/fast-import.c: pack lookup in store/stream - builtin/grep.c: pack preparation - builtin/pack-objects.c: cruft/kept pack enumeration Add a unit test verifying odb_source_files_try() returns the correct backend for ODB_SOURCE_FILES and NULL for other types. Note: repo_approximate_object_count() and has_object_pack() will not account for objects in non-files sources. These are display and optimization functions respectively, and a follow-up series can add vtable callbacks to address this. Signed-off-by: Aaron Paterson <apaterson@pm.me>
1 parent e6877b3 commit a8303b1

14 files changed

Lines changed: 117 additions & 35 deletions

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,6 +1544,7 @@ CLAR_TEST_SUITES += u-strvec
15441544
CLAR_TEST_SUITES += u-trailer
15451545
CLAR_TEST_SUITES += u-urlmatch-normalization
15461546
CLAR_TEST_SUITES += u-utf8-width
1547+
CLAR_TEST_SUITES += u-odb-source
15471548
CLAR_TEST_PROG = $(UNIT_TEST_BIN)/unit-tests$(X)
15481549
CLAR_TEST_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(CLAR_TEST_SUITES))
15491550
CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/clar/clar.o

builtin/cat-file.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -882,9 +882,12 @@ static void batch_each_object(struct batch_options *opt,
882882
struct object_info oi = { 0 };
883883

884884
for (source = the_repository->objects->sources; source; source = source->next) {
885-
struct odb_source_files *files = odb_source_files_downcast(source);
886-
int ret = packfile_store_for_each_object(files->packed, &oi,
887-
batch_one_object_oi, &payload, flags);
885+
struct odb_source_files *files = odb_source_files_try(source);
886+
int ret;
887+
if (!files)
888+
continue;
889+
ret = packfile_store_for_each_object(files->packed, &oi,
890+
batch_one_object_oi, &payload, flags);
888891
if (ret)
889892
break;
890893
}

builtin/fast-import.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -982,7 +982,9 @@ static int store_object(
982982
}
983983

984984
for (source = the_repository->objects->sources; source; source = source->next) {
985-
struct odb_source_files *files = odb_source_files_downcast(source);
985+
struct odb_source_files *files = odb_source_files_try(source);
986+
if (!files)
987+
continue;
986988

987989
if (!packfile_list_find_oid(packfile_store_get_packs(files->packed), &oid))
988990
continue;
@@ -1189,7 +1191,9 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
11891191
}
11901192

11911193
for (source = the_repository->objects->sources; source; source = source->next) {
1192-
struct odb_source_files *files = odb_source_files_downcast(source);
1194+
struct odb_source_files *files = odb_source_files_try(source);
1195+
if (!files)
1196+
continue;
11931197

11941198
if (!packfile_list_find_oid(packfile_store_get_packs(files->packed), &oid))
11951199
continue;

builtin/grep.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1219,7 +1219,9 @@ int cmd_grep(int argc,
12191219

12201220
odb_prepare_alternates(the_repository->objects);
12211221
for (source = the_repository->objects->sources; source; source = source->next) {
1222-
struct odb_source_files *files = odb_source_files_downcast(source);
1222+
struct odb_source_files *files = odb_source_files_try(source);
1223+
if (!files)
1224+
continue;
12231225
packfile_store_prepare(files->packed);
12241226
}
12251227
}

builtin/pack-objects.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,8 +1531,11 @@ static int want_cruft_object_mtime(struct repository *r,
15311531
struct odb_source *source;
15321532

15331533
for (source = r->objects->sources; source; source = source->next) {
1534-
struct odb_source_files *files = odb_source_files_downcast(source);
1535-
struct packed_git **cache = packfile_store_get_kept_pack_cache(files->packed, flags);
1534+
struct odb_source_files *files = odb_source_files_try(source);
1535+
struct packed_git **cache;
1536+
if (!files)
1537+
continue;
1538+
cache = packfile_store_get_kept_pack_cache(files->packed, flags);
15361539

15371540
for (; *cache; cache++) {
15381541
struct packed_git *p = *cache;
@@ -1754,7 +1757,9 @@ static int want_object_in_pack_mtime(const struct object_id *oid,
17541757
}
17551758

17561759
for (source = the_repository->objects->sources; source; source = source->next) {
1757-
struct odb_source_files *files = odb_source_files_downcast(source);
1760+
struct odb_source_files *files = odb_source_files_try(source);
1761+
if (!files)
1762+
continue;
17581763

17591764
for (e = files->packed->packs.head; e; e = e->next) {
17601765
struct packed_git *p = e->pack;
@@ -4350,7 +4355,9 @@ static void add_objects_in_unpacked_packs(void)
43504355

43514356
odb_prepare_alternates(to_pack.repo->objects);
43524357
for (source = to_pack.repo->objects->sources; source; source = source->next) {
4353-
struct odb_source_files *files = odb_source_files_downcast(source);
4358+
struct odb_source_files *files = odb_source_files_try(source);
4359+
if (!files)
4360+
continue;
43544361

43554362
if (!source->local)
43564363
continue;

commit-graph.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1981,7 +1981,9 @@ static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx)
19811981

19821982
odb_prepare_alternates(ctx->r->objects);
19831983
for (source = ctx->r->objects->sources; source; source = source->next) {
1984-
struct odb_source_files *files = odb_source_files_downcast(source);
1984+
struct odb_source_files *files = odb_source_files_try(source);
1985+
if (!files)
1986+
continue;
19851987
packfile_store_for_each_object(files->packed, &oi, add_packed_commits_oi,
19861988
ctx, ODB_FOR_EACH_OBJECT_PACK_ORDER);
19871989
}

loose.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,13 @@ static int insert_loose_map(struct odb_source *source,
6464

6565
static int load_one_loose_object_map(struct repository *repo, struct odb_source *source)
6666
{
67-
struct odb_source_files *files = odb_source_files_downcast(source);
67+
struct odb_source_files *files = odb_source_files_try(source);
6868
struct strbuf buf = STRBUF_INIT, path = STRBUF_INIT;
6969
FILE *fp;
7070

71+
if (!files)
72+
return 0;
73+
7174
if (!files->loose->map)
7275
loose_object_map_init(&files->loose->map);
7376
if (!files->loose->cache) {
@@ -235,8 +238,11 @@ int repo_loose_object_map_oid(struct repository *repo,
235238
khiter_t pos;
236239

237240
for (source = repo->objects->sources; source; source = source->next) {
238-
struct odb_source_files *files = odb_source_files_downcast(source);
239-
struct loose_object_map *loose_map = files->loose->map;
241+
struct odb_source_files *files = odb_source_files_try(source);
242+
struct loose_object_map *loose_map;
243+
if (!files)
244+
continue;
245+
loose_map = files->loose->map;
240246
if (!loose_map)
241247
continue;
242248
map = (to == repo->compat_hash_algo) ?

midx.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ static int midx_read_object_offsets(const unsigned char *chunk_start,
9595

9696
struct multi_pack_index *get_multi_pack_index(struct odb_source *source)
9797
{
98-
struct odb_source_files *files = odb_source_files_downcast(source);
98+
struct odb_source_files *files = odb_source_files_try(source);
99+
if (!files)
100+
return NULL;
99101
packfile_store_prepare(files->packed);
100102
return files->packed->midx;
101103
}
@@ -806,7 +808,9 @@ void clear_midx_file(struct repository *r)
806808
struct odb_source *source;
807809

808810
for (source = r->objects->sources; source; source = source->next) {
809-
struct odb_source_files *files = odb_source_files_downcast(source);
811+
struct odb_source_files *files = odb_source_files_try(source);
812+
if (!files)
813+
continue;
810814
if (files->packed->midx)
811815
close_midx(files->packed->midx);
812816
files->packed->midx = NULL;

object-file.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,14 +1879,20 @@ static int append_loose_object(const struct object_id *oid,
18791879
struct oidtree *odb_source_loose_cache(struct odb_source *source,
18801880
const struct object_id *oid)
18811881
{
1882-
struct odb_source_files *files = odb_source_files_downcast(source);
1883-
int subdir_nr = oid->hash[0];
1882+
struct odb_source_files *files = odb_source_files_try(source);
1883+
int subdir_nr;
18841884
struct strbuf buf = STRBUF_INIT;
1885-
size_t word_bits = bitsizeof(files->loose->subdir_seen[0]);
1886-
size_t word_index = subdir_nr / word_bits;
1887-
size_t mask = (size_t)1u << (subdir_nr % word_bits);
1885+
size_t word_bits, word_index, mask;
18881886
uint32_t *bitmap;
18891887

1888+
if (!files)
1889+
return NULL;
1890+
1891+
subdir_nr = oid->hash[0];
1892+
word_bits = bitsizeof(files->loose->subdir_seen[0]);
1893+
word_index = subdir_nr / word_bits;
1894+
mask = (size_t)1u << (subdir_nr % word_bits);
1895+
18901896
if (subdir_nr < 0 ||
18911897
(size_t) subdir_nr >= bitsizeof(files->loose->subdir_seen))
18921898
BUG("subdir_nr out of range");
@@ -1919,7 +1925,9 @@ static void odb_source_loose_clear_cache(struct odb_source_loose *loose)
19191925

19201926
void odb_source_loose_reprepare(struct odb_source *source)
19211927
{
1922-
struct odb_source_files *files = odb_source_files_downcast(source);
1928+
struct odb_source_files *files = odb_source_files_try(source);
1929+
if (!files)
1930+
return;
19231931
odb_source_loose_clear_cache(files->loose);
19241932
}
19251933

object-name.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,11 @@ static void find_short_object_filename(struct disambiguate_state *ds)
115115
{
116116
struct odb_source *source;
117117

118-
for (source = ds->repo->objects->sources; source && !ds->ambiguous; source = source->next)
119-
oidtree_each(odb_source_loose_cache(source, &ds->bin_pfx),
120-
&ds->bin_pfx, ds->len, match_prefix, ds);
118+
for (source = ds->repo->objects->sources; source && !ds->ambiguous; source = source->next) {
119+
struct oidtree *tree = odb_source_loose_cache(source, &ds->bin_pfx);
120+
if (tree)
121+
oidtree_each(tree, &ds->bin_pfx, ds->len, match_prefix, ds);
122+
}
121123
}
122124

123125
static int match_hash(unsigned len, const unsigned char *a, const unsigned char *b)

0 commit comments

Comments
 (0)