]> git.ipfire.org Git - thirdparty/git.git/commitdiff
midx: build `keep_hashes` array in order
authorTaylor Blau <me@ttaylorr.com>
Tue, 19 May 2026 15:57:45 +0000 (11:57 -0400)
committerJunio C Hamano <gitster@pobox.com>
Wed, 20 May 2026 02:31:13 +0000 (11:31 +0900)
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>
midx-write.c

index 9328f65a20187a9ac2fc50f65592a49d8f3eb7b2..55c778a97cbe59b7e4b7501364f451edc6f97c90 100644 (file)
@@ -1731,6 +1731,9 @@ static int write_midx_internal(struct write_midx_opts *opts)
                FILE *chainf = fdopen_lock_file(&lk, "w");
                struct strbuf final_midx_name = STRBUF_INIT;
                struct multi_pack_index *m = ctx.base_midx;
+               struct multi_pack_index **layers = NULL;
+               size_t layers_nr = 0, layers_alloc = 0;
+               size_t j = 0;
 
                if (!chainf) {
                        error_errno(_("unable to open multi-pack-index chain file"));
@@ -1751,46 +1754,49 @@ static int write_midx_internal(struct write_midx_opts *opts)
                strbuf_release(&final_midx_name);
 
                if (ctx.compact) {
-                       struct multi_pack_index *m;
-                       uint32_t num_layers_before_from = 0;
-                       uint32_t i;
+                       struct multi_pack_index *mp;
 
-                       for (m = ctx.base_midx; m; m = m->base_midx)
-                               num_layers_before_from++;
-
-                       m = ctx.base_midx;
-                       for (i = 0; i < num_layers_before_from; i++) {
-                               uint32_t j = num_layers_before_from - i - 1;
-
-                               keep_hashes[j] = xstrdup(midx_get_checksum_hex(m));
-                               m = m->base_midx;
+                       for (mp = ctx.base_midx; mp; mp = mp->base_midx) {
+                               ALLOC_GROW(layers, layers_nr + 1, layers_alloc);
+                               layers[layers_nr++] = mp;
                        }
+                       while (layers_nr)
+                               keep_hashes[j++] =
+                                       xstrdup(midx_get_checksum_hex(layers[--layers_nr]));
 
-                       keep_hashes[i] = xstrdup(hash_to_hex_algop(midx_hash,
-                                                                  r->hash_algo));
+                       keep_hashes[j++] =
+                               xstrdup(hash_to_hex_algop(midx_hash,
+                                                         r->hash_algo));
 
-                       i = 0;
-                       for (m = ctx.m;
-                            m && midx_hashcmp(m, ctx.compact_to, r->hash_algo);
-                            m = m->base_midx) {
-                               keep_hashes[keep_hashes_nr - i - 1] =
-                                       xstrdup(midx_get_checksum_hex(m));
-                               i++;
+                       for (mp = ctx.m;
+                            mp && midx_hashcmp(mp, ctx.compact_to,
+                                               r->hash_algo);
+                            mp = mp->base_midx) {
+                               ALLOC_GROW(layers, layers_nr + 1, layers_alloc);
+                               layers[layers_nr++] = mp;
                        }
+                       while (layers_nr)
+                               keep_hashes[j++] =
+                                       xstrdup(midx_get_checksum_hex(layers[--layers_nr]));
                } else {
-                       keep_hashes[ctx.num_multi_pack_indexes_before] =
+                       for (; m; m = m->base_midx) {
+                               ALLOC_GROW(layers, layers_nr + 1, layers_alloc);
+                               layers[layers_nr++] = m;
+                       }
+                       while (layers_nr)
+                               keep_hashes[j++] =
+                                       xstrdup(midx_get_checksum_hex(layers[--layers_nr]));
+
+                       keep_hashes[j++] =
                                xstrdup(hash_to_hex_algop(midx_hash,
                                                          r->hash_algo));
+               }
 
-                       for (uint32_t i = 0; i < ctx.num_multi_pack_indexes_before; i++) {
-                               uint32_t j = ctx.num_multi_pack_indexes_before - i - 1;
+               ASSERT(j == keep_hashes_nr);
 
-                               keep_hashes[j] = xstrdup(midx_get_checksum_hex(m));
-                               m = m->base_midx;
-                       }
-               }
+               free(layers);
 
-               for (uint32_t i = 0; i < keep_hashes_nr; i++)
+               for (uint32_t i = 0; i < j; i++)
                        fprintf(get_lock_file_fp(&lk), "%s\n", keep_hashes[i]);
        } else {
                keep_hashes[ctx.num_multi_pack_indexes_before] =