aboutsummaryrefslogtreecommitdiff
path: root/packfile.h
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2026-01-09 09:33:13 +0100
committerJunio C Hamano <gitster@pobox.com>2026-01-09 06:40:07 -0800
commit84f0e60b28de69d1ccb7a51b729af6202b6cf4c8 (patch)
treea3c5e619c5c692cab984a768feb6e81925520c0c /packfile.h
parenteb9ec52d95b74d80dd64190de1349aab740990c9 (diff)
downloadgit-84f0e60b28de69d1ccb7a51b729af6202b6cf4c8.tar.xz
packfile: move packfile store into object source
The packfile store is a member of `struct object_database`, which means that we have a single store per database. This doesn't really make much sense though: each source connected to the database has its own set of packfiles, so there is a conceptual mismatch here. This hasn't really caused much of a problem in the past, but with the advent of pluggable object databases this is becoming more of a problem because some of the sources may not even use packfiles in the first place. Move the packfile store down by one level from the object database into the object database source. This ensures that each source now has its own packfile store, and we can eventually start to abstract it away entirely so that the caller doesn't even know what kind of store it uses. Note that we only need to adjust a relatively small number of callers, way less than one might expect. This is because most callers are using `repo_for_each_pack()`, which handles enumeration of all packfiles that exist in the repository. So for now, none of these callers need to be adapted. The remaining callers that iterate through the packfiles directly and that need adjustment are those that are a bit more tangled with packfiles. These will be adjusted over time. Note that this patch only moves the packfile store, and there is still a bunch of functions that seemingly operate on a packfile store but that end up iterating over all sources. These will be adjusted in subsequent commits. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'packfile.h')
-rw-r--r--packfile.h62
1 files changed, 54 insertions, 8 deletions
diff --git a/packfile.h b/packfile.h
index 410f85f03d..07f7cdbad1 100644
--- a/packfile.h
+++ b/packfile.h
@@ -5,6 +5,7 @@
#include "object.h"
#include "odb.h"
#include "oidset.h"
+#include "repository.h"
#include "strmap.h"
/* in odb.h */
@@ -171,13 +172,64 @@ void packfile_store_add_pack(struct packfile_store *store,
struct packed_git *pack);
/*
+ * Get all packs managed by the given store, including packfiles that are
+ * referenced by multi-pack indices.
+ */
+struct packfile_list_entry *packfile_store_get_packs(struct packfile_store *store);
+
+struct repo_for_each_pack_data {
+ struct odb_source *source;
+ struct packfile_list_entry *entry;
+};
+
+static inline struct repo_for_each_pack_data repo_for_eack_pack_data_init(struct repository *repo)
+{
+ struct repo_for_each_pack_data data = { 0 };
+
+ odb_prepare_alternates(repo->objects);
+
+ for (struct odb_source *source = repo->objects->sources; source; source = source->next) {
+ struct packfile_list_entry *entry = packfile_store_get_packs(source->packfiles);
+ if (!entry)
+ continue;
+ data.source = source;
+ data.entry = entry;
+ break;
+ }
+
+ return data;
+}
+
+static inline void repo_for_each_pack_data_next(struct repo_for_each_pack_data *data)
+{
+ struct odb_source *source;
+
+ data->entry = data->entry->next;
+ if (data->entry)
+ return;
+
+ for (source = data->source->next; source; source = source->next) {
+ struct packfile_list_entry *entry = packfile_store_get_packs(source->packfiles);
+ if (!entry)
+ continue;
+ data->source = source;
+ data->entry = entry;
+ return;
+ }
+
+ data->source = NULL;
+ data->entry = NULL;
+}
+
+/*
* Load and iterate through all packs of the given repository. This helper
* function will yield packfiles from all object sources connected to the
* repository.
*/
#define repo_for_each_pack(repo, p) \
- for (struct packfile_list_entry *e = packfile_store_get_packs(repo->objects->packfiles); \
- ((p) = (e ? e->pack : NULL)); e = e->next)
+ for (struct repo_for_each_pack_data eack_pack_data = repo_for_eack_pack_data_init(repo); \
+ ((p) = (eack_pack_data.entry ? eack_pack_data.entry->pack : NULL)); \
+ repo_for_each_pack_data_next(&eack_pack_data))
int packfile_store_read_object_stream(struct odb_read_stream **out,
struct packfile_store *store,
@@ -195,12 +247,6 @@ int packfile_store_read_object_info(struct packfile_store *store,
unsigned flags);
/*
- * Get all packs managed by the given store, including packfiles that are
- * referenced by multi-pack indices.
- */
-struct packfile_list_entry *packfile_store_get_packs(struct packfile_store *store);
-
-/*
* Open the packfile and add it to the store if it isn't yet known. Returns
* either the newly opened packfile or the preexisting packfile. Returns a
* `NULL` pointer in case the packfile could not be opened.