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>
Patrick Steinhardt committed
Sep 23, 2025 at 12:17 UTC
14aaf5c9d889a4988ffc64b39fe38bd19b930a50
5 files changed
+26
-26
midx.c
+1
-1
@@ -460,7 +460,7 @@ int prepare_midx_pack(struct multi_pack_index *m,
460
strbuf_addbuf(&key, &pack_name);
461
strbuf_strip_suffix(&key, ".idx");
462
strbuf_addstr(&key, ".pack");
463
- p = hashmap_get_entry_from_hash(&r->objects->pack_map,
463
+ p = hashmap_get_entry_from_hash(&r->objects->packfiles->map,
464
strhash(key.buf), key.buf,
465
struct packed_git, packmap_ent);
466
if (!p) {
odb.c
-2
@@ -998,7 +998,6 @@ struct object_database *odb_new(struct repository *repo)
998
o->repo = repo;
999
o->packfiles = packfile_store_new(o);
1000
INIT_LIST_HEAD(&o->packed_git_mru);
1001
- hashmap_init(&o->pack_map, pack_map_entry_cmp, NULL, 0);
1001
pthread_mutex_init(&o->replace_mutex, NULL);
1002
string_list_init_dup(&o->submodule_source_paths);
1003
return o;
@@ -1041,6 +1040,5 @@ void odb_clear(struct object_database *o)
1040
packfile_store_free(o->packfiles);
1041
o->packfiles = NULL;
1042
1044
- hashmap_clear(&o->pack_map);
1043
string_list_clear(&o->submodule_source_paths, 0);
1044
}
odb.h
+1
-7
@@ -135,7 +135,7 @@ struct object_database {
135
/*
136
* private data
137
*
138
- * should only be accessed directly by packfile.c
138
+ * Should only be accessed directly by packfile.c and midx.c.
139
*/
140
struct packfile_store *packfiles;
141
/* A most-recently-used ordered version of the packed_git list. */
@@ -155,12 +155,6 @@ struct object_database {
155
struct cached_object_entry *cached_objects;
156
size_t cached_object_nr, cached_object_alloc;
157
158
- /*
159
- * A map of packfiles to packed_git structs for tracking which
160
- * packs have been loaded already.
161
- */
162
- struct hashmap pack_map;
163
-
158
/*
159
* A fast, rough count of the number of objects in the repository.
160
* These two fields are not meant for direct access. Use
packfile.c
+18
-2
@@ -788,7 +788,7 @@ void install_packed_git(struct repository *r, struct packed_git *pack)
788
r->objects->packfiles->packs = pack;
789
790
hashmap_entry_init(&pack->packmap_ent, strhash(pack->pack_name));
791
- hashmap_add(&r->objects->pack_map, &pack->packmap_ent);
791
+ hashmap_add(&r->objects->packfiles->map, &pack->packmap_ent);
792
}
793
794
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,
901
hashmap_entry_init(&hent, hash);
902
903
/* Don't reopen a pack we already have. */
904
- if (!hashmap_get(&data->r->objects->pack_map, &hent, pack_name)) {
904
+ if (!hashmap_get(&data->r->objects->packfiles->map, &hent, pack_name)) {
905
p = add_packed_git(data->r, full_name, full_name_len, data->local);
906
if (p)
907
install_packed_git(data->r, p);
@@ -2328,11 +2328,26 @@ int parse_pack_header_option(const char *in, unsigned char *out, unsigned int *l
2328
return 0;
2329
}
2330
2331
+static int pack_map_entry_cmp(const void *cmp_data UNUSED,
2332
+ const struct hashmap_entry *entry,
2333
+ const struct hashmap_entry *entry2,
2334
+ const void *keydata)
2335
+{
2336
+ const char *key = keydata;
2337
+ const struct packed_git *pg1, *pg2;
2338
+
2339
+ pg1 = container_of(entry, const struct packed_git, packmap_ent);
2340
+ pg2 = container_of(entry2, const struct packed_git, packmap_ent);
2341
+
2342
+ return strcmp(pg1->pack_name, key ? key : pg2->pack_name);
2343
+}
2344
+
2345
struct packfile_store *packfile_store_new(struct object_database *odb)
2346
{
2347
struct packfile_store *store;
2348
CALLOC_ARRAY(store, 1);
2349
store->odb = odb;
2350
+ hashmap_init(&store->map, pack_map_entry_cmp, NULL, 0);
2351
return store;
2352
}
2353
@@ -2342,6 +2357,7 @@ void packfile_store_free(struct packfile_store *store)
2357
next = p->next;
2358
free(p);
2359
}
2360
+ hashmap_clear(&store->map);
2361
free(store);
2362
}
2363
packfile.h
+6
-14
@@ -64,6 +64,12 @@ struct packfile_store {
64
*/
65
struct packed_git *packs;
66
67
+ /*
68
+ * A map of packfile names to packed_git structs for tracking which
69
+ * packs have been loaded already.
70
+ */
71
+ struct hashmap map;
72
+
73
/*
74
* Whether packfiles have already been populated with this store's
75
* packs.
@@ -89,20 +95,6 @@ void packfile_store_free(struct packfile_store *store);
95
*/
96
void packfile_store_close(struct packfile_store *store);
97
92
-static inline int pack_map_entry_cmp(const void *cmp_data UNUSED,
93
- const struct hashmap_entry *entry,
94
- const struct hashmap_entry *entry2,
95
- const void *keydata)
96
-{
97
- const char *key = keydata;
98
- const struct packed_git *pg1, *pg2;
99
-
100
- pg1 = container_of(entry, const struct packed_git, packmap_ent);
101
- pg2 = container_of(entry2, const struct packed_git, packmap_ent);
102
-
103
- return strcmp(pg1->pack_name, key ? key : pg2->pack_name);
104
-}
105
-
98
struct pack_window {
99
struct pack_window *next;
100
unsigned char *base;