odb/source-packed: start converting to a proper struct odb_source

Start converting `struct odb_source_packed` into a proper pluggable
`struct odb_source` by embedding the base struct and assigning it the
new `ODB_SOURCE_PACKED` type. Furthermore, wire up lifecycle management
of this source by implementing the `free` callback and taking ownership
of the chdir notifications.

Note that the packed source is not yet functional as a standalone `struct
odb_source`, as it's missing all of the callback implementations. These
will be wired up in subsequent commits.

Further note that we're also registering a `chdir_notify` callback to
reparent our path. This wasn't previously necessary (and still isn't at
this point in time) because all paths are taken from the owning "files"
source, and that source already handles the reparenting for us. But a
subsequent commit will change that so that we're using the path of the
"packed" source, and once that happens we'll need it to be updated when
changing the working directory.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Patrick Steinhardt
2026-06-17 08:39:48 +02:00
committed by Junio C Hamano
parent 3ac21e6d82
commit 0de2467e6c
6 changed files with 60 additions and 22 deletions

View File

@@ -29,7 +29,7 @@ static void odb_source_files_free(struct odb_source *source)
struct odb_source_files *files = odb_source_files_downcast(source);
chdir_notify_unregister(NULL, odb_source_files_reparent, files);
odb_source_free(&files->loose->base);
packfile_store_free(files->packed);
odb_source_free(&files->packed->base);
odb_source_release(&files->base);
free(files);
}

View File

@@ -1,11 +1,50 @@
#include "git-compat-util.h"
#include "abspath.h"
#include "chdir-notify.h"
#include "odb/source-packed.h"
#include "packfile.h"
static void odb_source_packed_reparent(const char *name UNUSED,
const char *old_cwd,
const char *new_cwd,
void *cb_data)
{
struct odb_source_packed *packed = cb_data;
char *path = reparent_relative_path(old_cwd, new_cwd,
packed->base.path);
free(packed->base.path);
packed->base.path = path;
}
static void odb_source_packed_free(struct odb_source *source)
{
struct odb_source_packed *packed = odb_source_packed_downcast(source);
chdir_notify_unregister(NULL, odb_source_packed_reparent, packed);
for (struct packfile_list_entry *e = packed->packs.head; e; e = e->next)
free(e->pack);
packfile_list_clear(&packed->packs);
strmap_clear(&packed->packs_by_path, 0);
odb_source_release(&packed->base);
free(packed);
}
struct odb_source_packed *odb_source_packed_new(struct odb_source_files *parent)
{
struct odb_source_packed *store;
CALLOC_ARRAY(store, 1);
store->files = parent;
strmap_init(&store->packs_by_path);
return store;
struct odb_source_packed *packed;
CALLOC_ARRAY(packed, 1);
odb_source_init(&packed->base, parent->base.odb, ODB_SOURCE_PACKED,
parent->base.path, parent->base.local);
packed->files = parent;
strmap_init(&packed->packs_by_path);
packed->base.free = odb_source_packed_free;
if (!is_absolute_path(parent->base.path))
chdir_notify_register(NULL, odb_source_packed_reparent, packed);
return packed;
}

View File

@@ -9,6 +9,7 @@
* A store that manages packfiles for a given object database.
*/
struct odb_source_packed {
struct odb_source base;
struct odb_source_files *files;
/*
@@ -69,4 +70,15 @@ struct odb_source_packed {
*/
struct odb_source_packed *odb_source_packed_new(struct odb_source_files *parent);
/*
* Cast the given object database source to the packed backend. This will cause
* a BUG in case the source doesn't use this backend.
*/
static inline struct odb_source_packed *odb_source_packed_downcast(struct odb_source *source)
{
if (source->type != ODB_SOURCE_PACKED)
BUG("trying to downcast source of type '%d' to packed", source->type);
return container_of(source, struct odb_source_packed, base);
}
#endif

View File

@@ -17,6 +17,9 @@ enum odb_source_type {
/* The "loose" backend that uses loose objects, only. */
ODB_SOURCE_LOOSE,
/* The "packed" backend that uses packfiles. */
ODB_SOURCE_PACKED,
/* The "in-memory" backend that stores objects in memory. */
ODB_SOURCE_INMEMORY,
};

View File

@@ -2749,16 +2749,6 @@ int parse_pack_header_option(const char *in, unsigned char *out, unsigned int *l
return 0;
}
void packfile_store_free(struct odb_source_packed *store)
{
for (struct packfile_list_entry *e = store->packs.head; e; e = e->next)
free(e->pack);
packfile_list_clear(&store->packs);
strmap_clear(&store->packs_by_path, 0);
free(store);
}
void packfile_store_close(struct odb_source_packed *store)
{
for (struct packfile_list_entry *e = store->packs.head; e; e = e->next) {

View File

@@ -55,12 +55,6 @@ struct packed_git {
char pack_name[FLEX_ARRAY]; /* more */
};
/*
* Free the packfile store and all its associated state. All packfiles
* tracked by the store will be closed.
*/
void packfile_store_free(struct odb_source_packed *store);
/*
* Close all packfiles associated with this store. The packfiles won't be
* free'd, so they can be re-opened at a later point in time.