packfile: use a `strmap` to store packs by name
To allow fast lookups of a packfile by name we use a hashmap that has the packfile name as key and the pack itself as value. But while this is the perfect use case for a `strmap`, we instead use `struct hashmap` and store the hashmap entry in the packfile itself. Simplify the code by using a `strmap` instead. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Oct 30, 2025 at 11:38 UTC
e78ab370545d81a950fa3b2701dd7c72015ee802
2 files changed
+6
-22
packfile.c
+4
-20
@@ -788,8 +788,7 @@ void packfile_store_add_pack(struct packfile_store *store,
788
pack->next = store->packs;
789
store->packs = pack;
790
791
- hashmap_entry_init(&pack->packmap_ent, strhash(pack->pack_name));
792
- hashmap_add(&store->map, &pack->packmap_ent);
791
+ strmap_put(&store->packs_by_path, pack->pack_name, pack);
792
}
793
794
struct packed_git *packfile_store_load_pack(struct packfile_store *store,
@@ -806,8 +805,7 @@ struct packed_git *packfile_store_load_pack(struct packfile_store *store,
805
strbuf_strip_suffix(&key, ".idx");
806
strbuf_addstr(&key, ".pack");
807
809
- p = hashmap_get_entry_from_hash(&store->map, strhash(key.buf), key.buf,
810
- struct packed_git, packmap_ent);
808
+ p = strmap_get(&store->packs_by_path, key.buf);
809
if (!p) {
810
p = add_packed_git(store->odb->repo, idx_path,
811
strlen(idx_path), local);
@@ -2311,27 +2309,13 @@ int parse_pack_header_option(const char *in, unsigned char *out, unsigned int *l
2309
return 0;
2310
}
2311
2314
-static int pack_map_entry_cmp(const void *cmp_data UNUSED,
2315
- const struct hashmap_entry *entry,
2316
- const struct hashmap_entry *entry2,
2317
- const void *keydata)
2318
-{
2319
- const char *key = keydata;
2320
- const struct packed_git *pg1, *pg2;
2321
-
2322
- pg1 = container_of(entry, const struct packed_git, packmap_ent);
2323
- pg2 = container_of(entry2, const struct packed_git, packmap_ent);
2324
-
2325
- return strcmp(pg1->pack_name, key ? key : pg2->pack_name);
2326
-}
2327
-
2312
struct packfile_store *packfile_store_new(struct object_database *odb)
2313
{
2314
struct packfile_store *store;
2315
CALLOC_ARRAY(store, 1);
2316
store->odb = odb;
2317
INIT_LIST_HEAD(&store->mru);
2334
- hashmap_init(&store->map, pack_map_entry_cmp, NULL, 0);
2318
+ strmap_init(&store->packs_by_path);
2319
return store;
2320
}
2321
@@ -2341,7 +2325,7 @@ void packfile_store_free(struct packfile_store *store)
2325
next = p->next;
2326
free(p);
2327
}
2344
- hashmap_clear(&store->map);
2328
+ strmap_clear(&store->packs_by_path, 0);
2329
free(store);
2330
}
2331
packfile.h
+2
-2
@@ -5,12 +5,12 @@
5
#include "object.h"
6
#include "odb.h"
7
#include "oidset.h"
8
+#include "strmap.h"
9
10
/* in odb.h */
11
struct object_info;
12
13
struct packed_git {
13
- struct hashmap_entry packmap_ent;
14
struct packed_git *next;
15
struct list_head mru;
16
struct pack_window *windows;
@@ -85,7 +85,7 @@ struct packfile_store {
85
* A map of packfile names to packed_git structs for tracking which
86
* packs have been loaded already.
87
*/
88
- struct hashmap map;
88
+ struct strmap packs_by_path;
89
90
/*
91
* Whether packfiles have already been populated with this store's