summaryrefslogtreecommitdiff
path: root/midx-write.c
diff options
context:
space:
mode:
Diffstat (limited to 'midx-write.c')
-rw-r--r--midx-write.c93
1 files changed, 62 insertions, 31 deletions
diff --git a/midx-write.c b/midx-write.c
index 48d6558253..ba4a94950a 100644
--- a/midx-write.c
+++ b/midx-write.c
@@ -647,18 +647,24 @@ static uint32_t *midx_pack_order(struct write_midx_context *ctx)
return pack_order;
}
-static void write_midx_reverse_index(char *midx_name, unsigned char *midx_hash,
- struct write_midx_context *ctx)
+static void write_midx_reverse_index(struct write_midx_context *ctx,
+ const char *object_dir,
+ unsigned char *midx_hash)
{
struct strbuf buf = STRBUF_INIT;
char *tmp_file;
trace2_region_enter("midx", "write_midx_reverse_index", ctx->repo);
- strbuf_addf(&buf, "%s-%s.rev", midx_name, hash_to_hex_algop(midx_hash,
- ctx->repo->hash_algo));
+ if (ctx->incremental)
+ get_split_midx_filename_ext(ctx->repo->hash_algo, &buf,
+ object_dir, midx_hash,
+ MIDX_EXT_REV);
+ else
+ get_midx_filename_ext(ctx->repo->hash_algo, &buf, object_dir,
+ midx_hash, MIDX_EXT_REV);
- tmp_file = write_rev_file_order(ctx->repo->hash_algo, NULL, ctx->pack_order,
+ tmp_file = write_rev_file_order(ctx->repo, NULL, ctx->pack_order,
ctx->entries_nr, midx_hash, WRITE_REV);
if (finalize_object_file(tmp_file, buf.buf))
@@ -708,7 +714,7 @@ static int add_ref_to_pending(const char *refname, const char *referent UNUSED,
if (!peel_iterated_oid(revs->repo, oid, &peeled))
oid = &peeled;
- object = parse_object_or_die(oid, refname);
+ object = parse_object_or_die(revs->repo, oid, refname);
if (object->type != OBJ_COMMIT)
return 0;
@@ -768,7 +774,7 @@ static int read_refs_snapshot(const char *refs_snapshot,
if (*end)
die(_("malformed line: %s"), buf.buf);
- object = parse_object_or_die(&oid, NULL);
+ object = parse_object_or_die(revs->repo, &oid, NULL);
if (preferred)
object->flags |= NEEDS_BITMAP;
@@ -829,22 +835,29 @@ static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr
return cb.commits;
}
-static int write_midx_bitmap(struct repository *r, const char *midx_name,
+static int write_midx_bitmap(struct write_midx_context *ctx,
+ const char *object_dir,
const unsigned char *midx_hash,
struct packing_data *pdata,
struct commit **commits,
uint32_t commits_nr,
- uint32_t *pack_order,
unsigned flags)
{
int ret, i;
uint16_t options = 0;
struct bitmap_writer writer;
struct pack_idx_entry **index;
- char *bitmap_name = xstrfmt("%s-%s.bitmap", midx_name,
- hash_to_hex_algop(midx_hash, r->hash_algo));
+ struct strbuf bitmap_name = STRBUF_INIT;
+
+ trace2_region_enter("midx", "write_midx_bitmap", ctx->repo);
- trace2_region_enter("midx", "write_midx_bitmap", r);
+ if (ctx->incremental)
+ get_split_midx_filename_ext(ctx->repo->hash_algo, &bitmap_name,
+ object_dir, midx_hash,
+ MIDX_EXT_BITMAP);
+ else
+ get_midx_filename_ext(ctx->repo->hash_algo, &bitmap_name,
+ object_dir, midx_hash, MIDX_EXT_BITMAP);
if (flags & MIDX_WRITE_BITMAP_HASH_CACHE)
options |= BITMAP_OPT_HASH_CACHE;
@@ -861,7 +874,8 @@ static int write_midx_bitmap(struct repository *r, const char *midx_name,
for (i = 0; i < pdata->nr_objects; i++)
index[i] = &pdata->objects[i].idx;
- bitmap_writer_init(&writer, r, pdata);
+ bitmap_writer_init(&writer, ctx->repo, pdata,
+ ctx->incremental ? ctx->base_midx : NULL);
bitmap_writer_show_progress(&writer, flags & MIDX_PROGRESS);
bitmap_writer_build_type_index(&writer, index);
@@ -879,7 +893,7 @@ static int write_midx_bitmap(struct repository *r, const char *midx_name,
* bitmap_writer_finish().
*/
for (i = 0; i < pdata->nr_objects; i++)
- index[pack_order[i]] = &pdata->objects[i].idx;
+ index[ctx->pack_order[i]] = &pdata->objects[i].idx;
bitmap_writer_select_commits(&writer, commits, commits_nr);
ret = bitmap_writer_build(&writer);
@@ -887,14 +901,14 @@ static int write_midx_bitmap(struct repository *r, const char *midx_name,
goto cleanup;
bitmap_writer_set_checksum(&writer, midx_hash);
- bitmap_writer_finish(&writer, index, bitmap_name, options);
+ bitmap_writer_finish(&writer, index, bitmap_name.buf, options);
cleanup:
free(index);
- free(bitmap_name);
+ strbuf_release(&bitmap_name);
bitmap_writer_free(&writer);
- trace2_region_leave("midx", "write_midx_bitmap", r);
+ trace2_region_leave("midx", "write_midx_bitmap", ctx->repo);
return ret;
}
@@ -1077,8 +1091,6 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
ctx.repo = r;
ctx.incremental = !!(flags & MIDX_WRITE_INCREMENTAL);
- if (ctx.incremental && (flags & MIDX_WRITE_BITMAP))
- die(_("cannot write incremental MIDX with bitmap"));
if (ctx.incremental)
strbuf_addf(&midx_name,
@@ -1086,7 +1098,7 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
object_dir);
else
get_midx_filename(r->hash_algo, &midx_name, object_dir);
- if (safe_create_leading_directories(midx_name.buf))
+ if (safe_create_leading_directories(r, midx_name.buf))
die_errno(_("unable to create leading directories of %s"),
midx_name.buf);
@@ -1119,6 +1131,13 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
if (ctx.incremental) {
struct multi_pack_index *m = ctx.base_midx;
while (m) {
+ if (flags & MIDX_WRITE_BITMAP && load_midx_revindex(m)) {
+ error(_("could not load reverse index for MIDX %s"),
+ hash_to_hex_algop(get_midx_checksum(m),
+ m->repo->hash_algo));
+ result = 1;
+ goto cleanup;
+ }
ctx.num_multi_pack_indexes_before++;
m = m->base_midx;
}
@@ -1342,10 +1361,12 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
return -1;
}
- f = hashfd(get_tempfile_fd(incr), get_tempfile_path(incr));
+ f = hashfd(r->hash_algo, get_tempfile_fd(incr),
+ get_tempfile_path(incr));
} else {
hold_lock_file_for_update(&lk, midx_name.buf, LOCK_DIE_ON_ERROR);
- f = hashfd(get_lock_file_fd(&lk), get_lock_file_path(&lk));
+ f = hashfd(r->hash_algo, get_lock_file_fd(&lk),
+ get_lock_file_path(&lk));
}
cf = init_chunkfile(f);
@@ -1387,7 +1408,7 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
if (flags & MIDX_WRITE_REV_INDEX &&
git_env_bool("GIT_TEST_MIDX_WRITE_REV", 0))
- write_midx_reverse_index(midx_name.buf, midx_hash, &ctx);
+ write_midx_reverse_index(&ctx, object_dir, midx_hash);
if (flags & MIDX_WRITE_BITMAP) {
struct packing_data pdata;
@@ -1410,8 +1431,8 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
FREE_AND_NULL(ctx.entries);
ctx.entries_nr = 0;
- if (write_midx_bitmap(r, midx_name.buf, midx_hash, &pdata,
- commits, commits_nr, ctx.pack_order,
+ if (write_midx_bitmap(&ctx, object_dir,
+ midx_hash, &pdata, commits, commits_nr,
flags) < 0) {
error(_("could not write multi-pack bitmap"));
result = 1;
@@ -1545,7 +1566,7 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
_("Counting referenced objects"),
m->num_objects);
for (i = 0; i < m->num_objects; i++) {
- int pack_int_id = nth_midxed_pack_int_id(m, i);
+ uint32_t pack_int_id = nth_midxed_pack_int_id(m, i);
count[pack_int_id]++;
display_progress(progress, i + 1);
}
@@ -1676,21 +1697,31 @@ static void fill_included_packs_batch(struct repository *r,
total_size = 0;
for (i = 0; total_size < batch_size && i < m->num_packs; i++) {
- int pack_int_id = pack_info[i].pack_int_id;
+ uint32_t pack_int_id = pack_info[i].pack_int_id;
struct packed_git *p = m->packs[pack_int_id];
- size_t expected_size;
+ uint64_t expected_size;
if (!want_included_pack(r, m, pack_kept_objects, pack_int_id))
continue;
- expected_size = st_mult(p->pack_size,
- pack_info[i].referenced_objects);
+ /*
+ * Use shifted integer arithmetic to calculate the
+ * expected pack size to ~4 significant digits without
+ * overflow for packsizes less that 1PB.
+ */
+ expected_size = (uint64_t)pack_info[i].referenced_objects << 14;
expected_size /= p->num_objects;
+ expected_size = u64_mult(expected_size, p->pack_size);
+ expected_size = u64_add(expected_size, 1u << 13) >> 14;
if (expected_size >= batch_size)
continue;
- total_size += expected_size;
+ if (unsigned_add_overflows(total_size, (size_t)expected_size))
+ total_size = SIZE_MAX;
+ else
+ total_size += expected_size;
+
include_pack[pack_int_id] = 1;
}