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.

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-09 10:50:58 +02:00
committed by Junio C Hamano
parent ef25514fe6
commit 1eb77914ab
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.