aboutsummaryrefslogtreecommitdiff
path: root/packfile.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2026-03-05 15:19:43 +0100
committerJunio C Hamano <gitster@pobox.com>2026-03-05 11:45:15 -0800
commitd9ecf268ef3f69130fa269012318470d908978f6 (patch)
tree66550ddc707f4f2c1a562201b33a89140f581bc5 /packfile.c
parentcb506a8a69c953f7b87bb3ae099e0bed8218d3ab (diff)
downloadgit-d9ecf268ef3f69130fa269012318470d908978f6.tar.xz
odb: embed base source in the "files" backend
The "files" backend is implemented as a pointer in the `struct odb_source`. This contradicts our typical pattern for pluggable backends like we use it for example in the ref store or for object database streams, where we typically embed the generic base structure in the specialized implementation. This pattern has a couple of small benefits: - We avoid an extra allocation. - We hide implementation details in the generic structure. - We can easily downcast from a generic backend to the specialized structure and vice versa because the offsets are known at compile time. - It becomes trivial to identify locations where we depend on backend specific logic because the cast needs to be explicit. Refactor our "files" object database source to do the same and embed the `struct odb_source` in the `struct odb_source_files`. There are still a bunch of sites in our code base where we do have to access internals of the "files" backend. The intent is that those will go away over time, but this will certainly take a while. Meanwhile, provide a `odb_source_files_downcast()` function that can convert a generic source into a "files" source. As we only have a single source the downcast succeeds unconditionally for now. Eventually though the intent is to make the cast `BUG()` in case the caller requests to downcast a non-"files" backend to a "files" backend. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'packfile.c')
-rw-r--r--packfile.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/packfile.c b/packfile.c
index 4e1f6087ed..da1c0dfa39 100644
--- a/packfile.c
+++ b/packfile.c
@@ -362,9 +362,11 @@ static int unuse_one_window(struct object_database *odb)
struct packed_git *lru_p = NULL;
struct pack_window *lru_w = NULL, *lru_l = NULL;
- for (source = odb->sources; source; source = source->next)
- for (e = source->files->packed->packs.head; e; e = e->next)
+ for (source = odb->sources; source; source = source->next) {
+ struct odb_source_files *files = odb_source_files_downcast(source);
+ for (e = files->packed->packs.head; e; e = e->next)
scan_windows(e->pack, &lru_p, &lru_w, &lru_l);
+ }
if (lru_p) {
munmap(lru_w->base, lru_w->len);
@@ -537,7 +539,8 @@ static int close_one_pack(struct repository *r)
int accept_windows_inuse = 1;
for (source = r->objects->sources; source; source = source->next) {
- for (e = source->files->packed->packs.head; e; e = e->next) {
+ struct odb_source_files *files = odb_source_files_downcast(source);
+ for (e = files->packed->packs.head; e; e = e->next) {
if (e->pack->pack_fd == -1)
continue;
find_lru_pack(e->pack, &lru_p, &mru_w, &accept_windows_inuse);
@@ -987,13 +990,14 @@ static void prepare_pack(const char *full_name, size_t full_name_len,
const char *file_name, void *_data)
{
struct prepare_pack_data *data = (struct prepare_pack_data *)_data;
+ struct odb_source_files *files = odb_source_files_downcast(data->source);
size_t base_len = full_name_len;
if (strip_suffix_mem(full_name, &base_len, ".idx") &&
- !(data->source->files->packed->midx &&
- midx_contains_pack(data->source->files->packed->midx, file_name))) {
+ !(files->packed->midx &&
+ midx_contains_pack(files->packed->midx, file_name))) {
char *trimmed_path = xstrndup(full_name, full_name_len);
- packfile_store_load_pack(data->source->files->packed,
+ packfile_store_load_pack(files->packed,
trimmed_path, data->source->local);
free(trimmed_path);
}
@@ -1247,8 +1251,10 @@ const struct packed_git *has_packed_and_bad(struct repository *r,
struct odb_source *source;
for (source = r->objects->sources; source; source = source->next) {
+ struct odb_source_files *files = odb_source_files_downcast(source);
struct packfile_list_entry *e;
- for (e = source->files->packed->packs.head; e; e = e->next)
+
+ for (e = files->packed->packs.head; e; e = e->next)
if (oidset_contains(&e->pack->bad_objects, oid))
return e->pack;
}
@@ -2254,7 +2260,8 @@ int has_object_pack(struct repository *r, const struct object_id *oid)
odb_prepare_alternates(r->objects);
for (source = r->objects->sources; source; source = source->next) {
- int ret = find_pack_entry(source->files->packed, oid, &e);
+ struct odb_source_files *files = odb_source_files_downcast(source);
+ int ret = find_pack_entry(files->packed, oid, &e);
if (ret)
return ret;
}
@@ -2269,9 +2276,10 @@ int has_object_kept_pack(struct repository *r, const struct object_id *oid,
struct pack_entry e;
for (source = r->objects->sources; source; source = source->next) {
+ struct odb_source_files *files = odb_source_files_downcast(source);
struct packed_git **cache;
- cache = packfile_store_get_kept_pack_cache(source->files->packed, flags);
+ cache = packfile_store_get_kept_pack_cache(files->packed, flags);
for (; *cache; cache++) {
struct packed_git *p = *cache;