midx: start tracking per object database source

Multi-pack indices are tracked via `struct multi_pack_index`. This data
structure is stored as a linked list inside `struct object_database`,
which is the global database that spans across all of the object
sources.

This layout causes two problems:

  - Object databases consist of multiple object sources (e.g. one source
    per alternate object directory), where each multi-pack index is
    specific to one of those sources. Regardless of that though, the
    MIDX is not tracked per source, but tracked globally for the whole
    object database. This creates a mismatch between the on-disk layout
    and how things are organized in the object database subsystems and
    makes some parts, like figuring out whether a source has an MIDX,
    quite awkward.

  - Multi-pack indices are an implementation detail of how efficient
    access for packfiles work. As such, they are neither relevant in the
    context of loose objects, nor in a potential future where we have
    pluggable backends.

Refactor `prepare_multi_pack_index_one()` so that it works on a specific
source, which allows us to easily store a pointer to the multi-pack
index inside of it. For now, this pointer exists next to the existing
linked list we have in the object database. Users will be adjusted in
subsequent patches to instead use the per-source pointers.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Patrick Steinhardt
2025-07-15 13:29:18 +02:00
committed by Junio C Hamano
parent c29998d1d4
commit 4d8be89d97
4 changed files with 24 additions and 11 deletions

19
midx.c
View File

@@ -724,28 +724,29 @@ int midx_preferred_pack(struct multi_pack_index *m, uint32_t *pack_int_id)
return 0;
}
int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, int local)
int prepare_multi_pack_index_one(struct odb_source *source, int local)
{
struct repository *r = source->odb->repo;
struct multi_pack_index *m;
struct multi_pack_index *m_search;
prepare_repo_settings(r);
if (!r->settings.core_multi_pack_index)
return 0;
for (m_search = r->objects->multi_pack_index; m_search; m_search = m_search->next)
if (!strcmp(object_dir, m_search->object_dir))
return 1;
m = load_multi_pack_index(r, object_dir, local);
if (source->midx)
return 1;
m = load_multi_pack_index(r, source->path, local);
if (m) {
struct multi_pack_index *mp = r->objects->multi_pack_index;
if (mp) {
m->next = mp->next;
mp->next = m;
} else
} else {
r->objects->multi_pack_index = m;
}
source->midx = m;
return 1;
}
@@ -837,6 +838,8 @@ void clear_midx_file(struct repository *r)
if (r->objects && r->objects->multi_pack_index) {
close_midx(r->objects->multi_pack_index);
r->objects->multi_pack_index = NULL;
for (struct odb_source *source = r->objects->sources; source; source = source->next)
source->midx = NULL;
}
if (remove_path(midx.buf))