Merge branch 'ps/midx-negative-packfile-cache'
When a stale .midx file refers to .pack files that no longer exist, we ended up checking for these non-existent files repeatedly, which has been optimized by memoizing the non-existence. * ps/midx-negative-packfile-cache: midx: stop repeatedly looking up nonexistent packfiles packfile: explain ordering of how we look up auxiliary pack filesmaint
commit
9a43523dc3
12
midx.c
12
midx.c
|
@ -13,6 +13,8 @@
|
||||||
#include "pack-bitmap.h"
|
#include "pack-bitmap.h"
|
||||||
#include "pack-revindex.h"
|
#include "pack-revindex.h"
|
||||||
|
|
||||||
|
#define MIDX_PACK_ERROR ((void *)(intptr_t)-1)
|
||||||
|
|
||||||
int midx_checksum_valid(struct multi_pack_index *m);
|
int midx_checksum_valid(struct multi_pack_index *m);
|
||||||
void clear_midx_files_ext(const char *object_dir, const char *ext,
|
void clear_midx_files_ext(const char *object_dir, const char *ext,
|
||||||
const char *keep_hash);
|
const char *keep_hash);
|
||||||
|
@ -405,7 +407,7 @@ void close_midx(struct multi_pack_index *m)
|
||||||
munmap((unsigned char *)m->data, m->data_len);
|
munmap((unsigned char *)m->data, m->data_len);
|
||||||
|
|
||||||
for (i = 0; i < m->num_packs; i++) {
|
for (i = 0; i < m->num_packs; i++) {
|
||||||
if (m->packs[i])
|
if (m->packs[i] && m->packs[i] != MIDX_PACK_ERROR)
|
||||||
m->packs[i]->multi_pack_index = 0;
|
m->packs[i]->multi_pack_index = 0;
|
||||||
}
|
}
|
||||||
FREE_AND_NULL(m->packs);
|
FREE_AND_NULL(m->packs);
|
||||||
|
@ -458,6 +460,8 @@ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m,
|
||||||
|
|
||||||
pack_int_id = midx_for_pack(&m, pack_int_id);
|
pack_int_id = midx_for_pack(&m, pack_int_id);
|
||||||
|
|
||||||
|
if (m->packs[pack_int_id] == MIDX_PACK_ERROR)
|
||||||
|
return 1;
|
||||||
if (m->packs[pack_int_id])
|
if (m->packs[pack_int_id])
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -482,8 +486,10 @@ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m,
|
||||||
strbuf_release(&pack_name);
|
strbuf_release(&pack_name);
|
||||||
strbuf_release(&key);
|
strbuf_release(&key);
|
||||||
|
|
||||||
if (!p)
|
if (!p) {
|
||||||
|
m->packs[pack_int_id] = MIDX_PACK_ERROR;
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
p->multi_pack_index = 1;
|
p->multi_pack_index = 1;
|
||||||
m->packs[pack_int_id] = p;
|
m->packs[pack_int_id] = p;
|
||||||
|
@ -495,6 +501,8 @@ struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
|
||||||
uint32_t pack_int_id)
|
uint32_t pack_int_id)
|
||||||
{
|
{
|
||||||
uint32_t local_pack_int_id = midx_for_pack(&m, pack_int_id);
|
uint32_t local_pack_int_id = midx_for_pack(&m, pack_int_id);
|
||||||
|
if (m->packs[local_pack_int_id] == MIDX_PACK_ERROR)
|
||||||
|
return NULL;
|
||||||
return m->packs[local_pack_int_id];
|
return m->packs[local_pack_int_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
packfile.c
11
packfile.c
|
@ -737,6 +737,17 @@ struct packed_git *add_packed_git(struct repository *r, const char *path,
|
||||||
p = alloc_packed_git(r, alloc);
|
p = alloc_packed_git(r, alloc);
|
||||||
memcpy(p->pack_name, path, path_len);
|
memcpy(p->pack_name, path, path_len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that we have to check auxiliary data structures before we check
|
||||||
|
* for the ".pack" file to exist to avoid races with a packfile that is
|
||||||
|
* in the process of being deleted. The ".pack" file is unlinked before
|
||||||
|
* its auxiliary data structures, so we know that we either get a
|
||||||
|
* consistent snapshot of all data structures or that we'll fail to
|
||||||
|
* stat(3p) the packfile itself and thus return `NULL`.
|
||||||
|
*
|
||||||
|
* As such, we cannot bail out before the access(3p) calls in case the
|
||||||
|
* packfile doesn't exist without doing two stat(3p) calls for it.
|
||||||
|
*/
|
||||||
xsnprintf(p->pack_name + path_len, alloc - path_len, ".keep");
|
xsnprintf(p->pack_name + path_len, alloc - path_len, ".keep");
|
||||||
if (!access(p->pack_name, F_OK))
|
if (!access(p->pack_name, F_OK))
|
||||||
p->pack_keep = 1;
|
p->pack_keep = 1;
|
||||||
|
|
Loading…
Reference in New Issue