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] =