midx: build `keep_hashes` array in order
Instead of filling the keep_hashes array using reverse indexing (e.g., `keep_hashes[count - i - 1]`) while traversing linked lists forward, collect linked list nodes into a temporary `layers` array and then iterate it backwards to fill `keep_hashes` sequentially. This makes the filling logic easier to follow, since each segment of the array is filled with a simple forward-marching index. Moreover, this change prepares us for a subsequent commit that will switch to using a `strvec`. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Taylor Blau committed
May 19, 2026 at 11:57 UTC
3a5ebfac2f8910f335dc1f269e8a8cbdcacb7157
1 file changed
+35
-29
midx-write.c
+35
-29
@@ -1731,6 +1731,9 @@ static int write_midx_internal(struct write_midx_opts *opts)
1731
FILE *chainf = fdopen_lock_file(&lk, "w");
1732
struct strbuf final_midx_name = STRBUF_INIT;
1733
struct multi_pack_index *m = ctx.base_midx;
1734
+ struct multi_pack_index **layers = NULL;
1735
+ size_t layers_nr = 0, layers_alloc = 0;
1736
+ size_t j = 0;
1737
1738
if (!chainf) {
1739
error_errno(_("unable to open multi-pack-index chain file"));
@@ -1751,46 +1754,49 @@ static int write_midx_internal(struct write_midx_opts *opts)
1754
strbuf_release(&final_midx_name);
1755
1756
if (ctx.compact) {
1754
- struct multi_pack_index *m;
1755
- uint32_t num_layers_before_from = 0;
1756
- uint32_t i;
1757
+ struct multi_pack_index *mp;
1758
1758
- for (m = ctx.base_midx; m; m = m->base_midx)
1759
- num_layers_before_from++;
1760
-
1761
- m = ctx.base_midx;
1762
- for (i = 0; i < num_layers_before_from; i++) {
1763
- uint32_t j = num_layers_before_from - i - 1;
1764
-
1765
- keep_hashes[j] = xstrdup(midx_get_checksum_hex(m));
1766
- m = m->base_midx;
1759
+ for (mp = ctx.base_midx; mp; mp = mp->base_midx) {
1760
+ ALLOC_GROW(layers, layers_nr + 1, layers_alloc);
1761
+ layers[layers_nr++] = mp;
1762
}
1763
+ while (layers_nr)
1764
+ keep_hashes[j++] =
1765
+ xstrdup(midx_get_checksum_hex(layers[--layers_nr]));
1766
1769
- keep_hashes[i] = xstrdup(hash_to_hex_algop(midx_hash,
1770
- r->hash_algo));
1767
+ keep_hashes[j++] =
1768
+ xstrdup(hash_to_hex_algop(midx_hash,
1769
+ r->hash_algo));
1770
1772
- i = 0;
1773
- for (m = ctx.m;
1774
- m && midx_hashcmp(m, ctx.compact_to, r->hash_algo);
1775
- m = m->base_midx) {
1776
- keep_hashes[keep_hashes_nr - i - 1] =
1777
- xstrdup(midx_get_checksum_hex(m));
1778
- i++;
1771
+ for (mp = ctx.m;
1772
+ mp && midx_hashcmp(mp, ctx.compact_to,
1773
+ r->hash_algo);
1774
+ mp = mp->base_midx) {
1775
+ ALLOC_GROW(layers, layers_nr + 1, layers_alloc);
1776
+ layers[layers_nr++] = mp;
1777
}
1778
+ while (layers_nr)
1779
+ keep_hashes[j++] =
1780
+ xstrdup(midx_get_checksum_hex(layers[--layers_nr]));
1781
} else {
1781
- keep_hashes[ctx.num_multi_pack_indexes_before] =
1782
+ for (; m; m = m->base_midx) {
1783
+ ALLOC_GROW(layers, layers_nr + 1, layers_alloc);
1784
+ layers[layers_nr++] = m;
1785
+ }
1786
+ while (layers_nr)
1787
+ keep_hashes[j++] =
1788
+ xstrdup(midx_get_checksum_hex(layers[--layers_nr]));
1789
+
1790
+ keep_hashes[j++] =
1791
xstrdup(hash_to_hex_algop(midx_hash,
1792
r->hash_algo));
1793
+ }
1794
1785
- for (uint32_t i = 0; i < ctx.num_multi_pack_indexes_before; i++) {
1786
- uint32_t j = ctx.num_multi_pack_indexes_before - i - 1;
1795
+ ASSERT(j == keep_hashes_nr);
1796
1788
- keep_hashes[j] = xstrdup(midx_get_checksum_hex(m));
1789
- m = m->base_midx;
1790
- }
1791
- }
1797
+ free(layers);
1798
1793
- for (uint32_t i = 0; i < keep_hashes_nr; i++)
1799
+ for (uint32_t i = 0; i < j; i++)
1800
fprintf(get_lock_file_fp(&lk), "%s\n", keep_hashes[i]);
1801
} else {
1802
keep_hashes[ctx.num_multi_pack_indexes_before] =