midx: use `strset` for retained MIDX files

Both `clear_midx_files_ext()` and `clear_incremental_midx_files_ext()`
build a list of filenames to keep while pruning stale MIDX files. Today
they hand-roll an array instead of using a `strset`, thus requiring us
to pass an additional length parameter, and makes lookups linear.

Replace the bare array with a `strset` which can be passed around as a
single parameter. Though it improves lookup performance, the difference
is likely immeasurable given how small the keep_hashes array typically
is.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
main
Taylor Blau 2026-05-19 11:57:42 -04:00 committed by Junio C Hamano
parent 2223513640
commit ddaa7a6fb7
1 changed files with 27 additions and 30 deletions

57
midx.c
View File

@ -758,8 +758,7 @@ int midx_checksum_valid(struct multi_pack_index *m)
}

struct clear_midx_data {
char **keep;
uint32_t keep_nr;
struct strset keep;
const char *ext;
};

@ -767,15 +766,12 @@ static void clear_midx_file_ext(const char *full_path, size_t full_path_len UNUS
const char *file_name, void *_data)
{
struct clear_midx_data *data = _data;
uint32_t i;

if (!(starts_with(file_name, "multi-pack-index-") &&
ends_with(file_name, data->ext)))
return;
for (i = 0; i < data->keep_nr; i++) {
if (!strcmp(data->keep[i], file_name))
return;
}
if (strset_contains(&data->keep, file_name))
return;
if (unlink(full_path))
die_errno(_("failed to remove %s"), full_path);
}
@ -783,48 +779,49 @@ static void clear_midx_file_ext(const char *full_path, size_t full_path_len UNUS
void clear_midx_files_ext(struct odb_source *source, const char *ext,
const char *keep_hash)
{
struct clear_midx_data data;
memset(&data, 0, sizeof(struct clear_midx_data));
struct clear_midx_data data = {
.keep = STRSET_INIT,
.ext = ext,
};

if (keep_hash) {
ALLOC_ARRAY(data.keep, 1);
struct strbuf buf = STRBUF_INIT;
strbuf_addf(&buf, "multi-pack-index-%s.%s", keep_hash, ext);

data.keep[0] = xstrfmt("multi-pack-index-%s.%s", keep_hash, ext);
data.keep_nr = 1;
strset_add(&data.keep, buf.buf);

strbuf_release(&buf);
}
data.ext = ext;

for_each_file_in_pack_dir(source->path,
clear_midx_file_ext,
&data);
for_each_file_in_pack_dir(source->path, clear_midx_file_ext, &data);

if (keep_hash)
free(data.keep[0]);
free(data.keep);
strset_clear(&data.keep);
}

void clear_incremental_midx_files_ext(struct odb_source *source, const char *ext,
char **keep_hashes,
uint32_t hashes_nr)
{
struct clear_midx_data data;
struct clear_midx_data data = {
.keep = STRSET_INIT,
.ext = ext,
};
struct strbuf buf = STRBUF_INIT;
uint32_t i;

memset(&data, 0, sizeof(struct clear_midx_data));
for (i = 0; i < hashes_nr; i++) {
strbuf_reset(&buf);
strbuf_addf(&buf, "multi-pack-index-%s.%s", keep_hashes[i],
ext);

ALLOC_ARRAY(data.keep, hashes_nr);
for (i = 0; i < hashes_nr; i++)
data.keep[i] = xstrfmt("multi-pack-index-%s.%s", keep_hashes[i],
ext);
data.keep_nr = hashes_nr;
data.ext = ext;
strset_add(&data.keep, buf.buf);
}

for_each_file_in_pack_subdir(source->path, "multi-pack-index.d",
clear_midx_file_ext, &data);

for (i = 0; i < hashes_nr; i++)
free(data.keep[i]);
free(data.keep);
strbuf_release(&buf);
strset_clear(&data.keep);
}

void clear_midx_file(struct repository *r)