odb: move packfile map into `struct packfile_store`

The object database tracks a map of packfiles by their respective paths,
which is used to figure out whether a given packfile has already been
loaded. With the introduction of the `struct packfile_store` we have a
better place to host this list though.

Move the map accordingly.

`pack_map_entry_cmp()` isn't used anywhere but in "packfile.c" anymore
after this change, so we convert it to a static function, as well. Note
that we also drop the `inline` hint: the function is used as a callback
function exclusively, and callbacks cannot be inlined.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
main
Patrick Steinhardt 2025-09-23 12:17:03 +02:00 committed by Junio C Hamano
parent 3421cb56a8
commit 14aaf5c9d8
5 changed files with 26 additions and 26 deletions

2
midx.c
View File

@ -460,7 +460,7 @@ int prepare_midx_pack(struct multi_pack_index *m,
strbuf_addbuf(&key, &pack_name); strbuf_addbuf(&key, &pack_name);
strbuf_strip_suffix(&key, ".idx"); strbuf_strip_suffix(&key, ".idx");
strbuf_addstr(&key, ".pack"); strbuf_addstr(&key, ".pack");
p = hashmap_get_entry_from_hash(&r->objects->pack_map, p = hashmap_get_entry_from_hash(&r->objects->packfiles->map,
strhash(key.buf), key.buf, strhash(key.buf), key.buf,
struct packed_git, packmap_ent); struct packed_git, packmap_ent);
if (!p) { if (!p) {

2
odb.c
View File

@ -998,7 +998,6 @@ struct object_database *odb_new(struct repository *repo)
o->repo = repo; o->repo = repo;
o->packfiles = packfile_store_new(o); o->packfiles = packfile_store_new(o);
INIT_LIST_HEAD(&o->packed_git_mru); INIT_LIST_HEAD(&o->packed_git_mru);
hashmap_init(&o->pack_map, pack_map_entry_cmp, NULL, 0);
pthread_mutex_init(&o->replace_mutex, NULL); pthread_mutex_init(&o->replace_mutex, NULL);
string_list_init_dup(&o->submodule_source_paths); string_list_init_dup(&o->submodule_source_paths);
return o; return o;
@ -1041,6 +1040,5 @@ void odb_clear(struct object_database *o)
packfile_store_free(o->packfiles); packfile_store_free(o->packfiles);
o->packfiles = NULL; o->packfiles = NULL;


hashmap_clear(&o->pack_map);
string_list_clear(&o->submodule_source_paths, 0); string_list_clear(&o->submodule_source_paths, 0);
} }

8
odb.h
View File

@ -135,7 +135,7 @@ struct object_database {
/* /*
* private data * private data
* *
* should only be accessed directly by packfile.c * Should only be accessed directly by packfile.c and midx.c.
*/ */
struct packfile_store *packfiles; struct packfile_store *packfiles;
/* A most-recently-used ordered version of the packed_git list. */ /* A most-recently-used ordered version of the packed_git list. */
@ -155,12 +155,6 @@ struct object_database {
struct cached_object_entry *cached_objects; struct cached_object_entry *cached_objects;
size_t cached_object_nr, cached_object_alloc; size_t cached_object_nr, cached_object_alloc;


/*
* A map of packfiles to packed_git structs for tracking which
* packs have been loaded already.
*/
struct hashmap pack_map;

/* /*
* A fast, rough count of the number of objects in the repository. * A fast, rough count of the number of objects in the repository.
* These two fields are not meant for direct access. Use * These two fields are not meant for direct access. Use

View File

@ -788,7 +788,7 @@ void install_packed_git(struct repository *r, struct packed_git *pack)
r->objects->packfiles->packs = pack; r->objects->packfiles->packs = pack;


hashmap_entry_init(&pack->packmap_ent, strhash(pack->pack_name)); hashmap_entry_init(&pack->packmap_ent, strhash(pack->pack_name));
hashmap_add(&r->objects->pack_map, &pack->packmap_ent); hashmap_add(&r->objects->packfiles->map, &pack->packmap_ent);
} }


void (*report_garbage)(unsigned seen_bits, const char *path); void (*report_garbage)(unsigned seen_bits, const char *path);
@ -901,7 +901,7 @@ static void prepare_pack(const char *full_name, size_t full_name_len,
hashmap_entry_init(&hent, hash); hashmap_entry_init(&hent, hash);


/* Don't reopen a pack we already have. */ /* Don't reopen a pack we already have. */
if (!hashmap_get(&data->r->objects->pack_map, &hent, pack_name)) { if (!hashmap_get(&data->r->objects->packfiles->map, &hent, pack_name)) {
p = add_packed_git(data->r, full_name, full_name_len, data->local); p = add_packed_git(data->r, full_name, full_name_len, data->local);
if (p) if (p)
install_packed_git(data->r, p); install_packed_git(data->r, p);
@ -2328,11 +2328,26 @@ int parse_pack_header_option(const char *in, unsigned char *out, unsigned int *l
return 0; return 0;
} }


static int pack_map_entry_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *entry,
const struct hashmap_entry *entry2,
const void *keydata)
{
const char *key = keydata;
const struct packed_git *pg1, *pg2;

pg1 = container_of(entry, const struct packed_git, packmap_ent);
pg2 = container_of(entry2, const struct packed_git, packmap_ent);

return strcmp(pg1->pack_name, key ? key : pg2->pack_name);
}

struct packfile_store *packfile_store_new(struct object_database *odb) struct packfile_store *packfile_store_new(struct object_database *odb)
{ {
struct packfile_store *store; struct packfile_store *store;
CALLOC_ARRAY(store, 1); CALLOC_ARRAY(store, 1);
store->odb = odb; store->odb = odb;
hashmap_init(&store->map, pack_map_entry_cmp, NULL, 0);
return store; return store;
} }


@ -2342,6 +2357,7 @@ void packfile_store_free(struct packfile_store *store)
next = p->next; next = p->next;
free(p); free(p);
} }
hashmap_clear(&store->map);
free(store); free(store);
} }



View File

@ -64,6 +64,12 @@ struct packfile_store {
*/ */
struct packed_git *packs; struct packed_git *packs;


/*
* A map of packfile names to packed_git structs for tracking which
* packs have been loaded already.
*/
struct hashmap map;

/* /*
* Whether packfiles have already been populated with this store's * Whether packfiles have already been populated with this store's
* packs. * packs.
@ -89,20 +95,6 @@ void packfile_store_free(struct packfile_store *store);
*/ */
void packfile_store_close(struct packfile_store *store); void packfile_store_close(struct packfile_store *store);


static inline int pack_map_entry_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *entry,
const struct hashmap_entry *entry2,
const void *keydata)
{
const char *key = keydata;
const struct packed_git *pg1, *pg2;

pg1 = container_of(entry, const struct packed_git, packmap_ent);
pg2 = container_of(entry2, const struct packed_git, packmap_ent);

return strcmp(pg1->pack_name, key ? key : pg2->pack_name);
}

struct pack_window { struct pack_window {
struct pack_window *next; struct pack_window *next;
unsigned char *base; unsigned char *base;