Skip to content

Commit d67530f

Browse files
pks-tgitster
authored andcommitted
packfile: introduce function to load and add packfiles
We have a recurring pattern where we essentially perform an upsert of a packfile in case it isn't yet known by the packfile store. The logic to do so is non-trivial as we have to reconstruct the packfile's key, check the map of packfiles, then create the new packfile and finally add it to the store. Introduce a new function that does this dance for us. Refactor callsites to use it. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f6f236d commit d67530f

File tree

5 files changed

+48
-41
lines changed

5 files changed

+48
-41
lines changed

builtin/fast-import.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -897,11 +897,11 @@ static void end_packfile(void)
897897
idx_name = keep_pack(create_index());
898898

899899
/* Register the packfile with core git's machinery. */
900-
new_p = add_packed_git(pack_data->repo, idx_name, strlen(idx_name), 1);
900+
new_p = packfile_store_load_pack(pack_data->repo->objects->packfiles,
901+
idx_name, 1);
901902
if (!new_p)
902903
die("core git rejected index %s", idx_name);
903904
all_packs[pack_id] = new_p;
904-
packfile_store_add_pack(the_repository->objects->packfiles, new_p);
905905
free(idx_name);
906906

907907
/* Print the boundary */

builtin/index-pack.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,13 +1640,9 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
16401640
rename_tmp_packfile(&final_index_name, curr_index_name, &index_name,
16411641
hash, "idx", 1);
16421642

1643-
if (do_fsck_object) {
1644-
struct packed_git *p;
1645-
p = add_packed_git(the_repository, final_index_name,
1646-
strlen(final_index_name), 0);
1647-
if (p)
1648-
packfile_store_add_pack(the_repository->objects->packfiles, p);
1649-
}
1643+
if (do_fsck_object)
1644+
packfile_store_load_pack(the_repository->objects->packfiles,
1645+
final_index_name, 0);
16501646

16511647
if (!from_stdin) {
16521648
printf("%s\n", hash_to_hex(hash));

midx.c

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,6 @@ int prepare_midx_pack(struct multi_pack_index *m,
443443
{
444444
struct repository *r = m->source->odb->repo;
445445
struct strbuf pack_name = STRBUF_INIT;
446-
struct strbuf key = STRBUF_INIT;
447446
struct packed_git *p;
448447

449448
pack_int_id = midx_for_pack(&m, pack_int_id);
@@ -455,25 +454,11 @@ int prepare_midx_pack(struct multi_pack_index *m,
455454

456455
strbuf_addf(&pack_name, "%s/pack/%s", m->source->path,
457456
m->pack_names[pack_int_id]);
458-
459-
/* pack_map holds the ".pack" name, but we have the .idx */
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->packfiles->map,
464-
strhash(key.buf), key.buf,
465-
struct packed_git, packmap_ent);
466-
if (!p) {
467-
p = add_packed_git(r, pack_name.buf, pack_name.len,
468-
m->source->local);
469-
if (p) {
470-
packfile_store_add_pack(r->objects->packfiles, p);
471-
list_add_tail(&p->mru, &r->objects->packfiles->mru);
472-
}
473-
}
474-
457+
p = packfile_store_load_pack(r->objects->packfiles,
458+
pack_name.buf, m->source->local);
459+
if (p)
460+
list_add_tail(&p->mru, &r->objects->packfiles->mru);
475461
strbuf_release(&pack_name);
476-
strbuf_release(&key);
477462

478463
if (!p) {
479464
m->packs[pack_int_id] = MIDX_PACK_ERROR;

packfile.c

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,33 @@ void packfile_store_add_pack(struct packfile_store *store,
792792
hashmap_add(&store->map, &pack->packmap_ent);
793793
}
794794

795+
struct packed_git *packfile_store_load_pack(struct packfile_store *store,
796+
const char *idx_path, int local)
797+
{
798+
struct strbuf key = STRBUF_INIT;
799+
struct packed_git *p;
800+
801+
/*
802+
* We're being called with the path to the index file, but `pack_map`
803+
* holds the path to the packfile itself.
804+
*/
805+
strbuf_addstr(&key, idx_path);
806+
strbuf_strip_suffix(&key, ".idx");
807+
strbuf_addstr(&key, ".pack");
808+
809+
p = hashmap_get_entry_from_hash(&store->map, strhash(key.buf), key.buf,
810+
struct packed_git, packmap_ent);
811+
if (!p) {
812+
p = add_packed_git(store->odb->repo, idx_path,
813+
strlen(idx_path), local);
814+
if (p)
815+
packfile_store_add_pack(store, p);
816+
}
817+
818+
strbuf_release(&key);
819+
return p;
820+
}
821+
795822
void (*report_garbage)(unsigned seen_bits, const char *path);
796823

797824
static void report_helper(const struct string_list *list,
@@ -891,23 +918,14 @@ static void prepare_pack(const char *full_name, size_t full_name_len,
891918
const char *file_name, void *_data)
892919
{
893920
struct prepare_pack_data *data = (struct prepare_pack_data *)_data;
894-
struct packed_git *p;
895921
size_t base_len = full_name_len;
896922

897923
if (strip_suffix_mem(full_name, &base_len, ".idx") &&
898924
!(data->m && midx_contains_pack(data->m, file_name))) {
899-
struct hashmap_entry hent;
900-
char *pack_name = xstrfmt("%.*s.pack", (int)base_len, full_name);
901-
unsigned int hash = strhash(pack_name);
902-
hashmap_entry_init(&hent, hash);
903-
904-
/* Don't reopen a pack we already have. */
905-
if (!hashmap_get(&data->r->objects->packfiles->map, &hent, pack_name)) {
906-
p = add_packed_git(data->r, full_name, full_name_len, data->local);
907-
if (p)
908-
packfile_store_add_pack(data->r->objects->packfiles, p);
909-
}
910-
free(pack_name);
925+
char *trimmed_path = xstrndup(full_name, full_name_len);
926+
packfile_store_load_pack(data->r->objects->packfiles,
927+
trimmed_path, data->local);
928+
free(trimmed_path);
911929
}
912930

913931
if (!report_garbage)

packfile.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,14 @@ void packfile_store_reprepare(struct packfile_store *store);
127127
void packfile_store_add_pack(struct packfile_store *store,
128128
struct packed_git *pack);
129129

130+
/*
131+
* Open the packfile and add it to the store if it isn't yet known. Returns
132+
* either the newly opened packfile or the preexisting packfile. Returns a
133+
* `NULL` pointer in case the packfile could not be opened.
134+
*/
135+
struct packed_git *packfile_store_load_pack(struct packfile_store *store,
136+
const char *idx_path, int local);
137+
130138
struct pack_window {
131139
struct pack_window *next;
132140
unsigned char *base;

0 commit comments

Comments
 (0)