summaryrefslogtreecommitdiff
path: root/range-diff.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-09-18 10:07:02 -0700
committerJunio C Hamano <gitster@pobox.com>2025-09-18 10:07:02 -0700
commit7b776bc308f904850f36a82e19f9775e672d464c (patch)
tree90f0638597e3c9be9360f3b35f5ac986dd9e7fa2 /range-diff.c
parent44c0d062bd2fed84ba1ac930a153de37a5280cd3 (diff)
parent00727249ec8404c68391ec58e9c9f0d8a88d5ca0 (diff)
Merge branch 'pc/range-diff-memory-limit'
"git range-diff" learned a way to limit the memory consumed by O(N*N) cost matrix. * pc/range-diff-memory-limit: range-diff: add configurable memory limit for cost matrix
Diffstat (limited to 'range-diff.c')
-rw-r--r--range-diff.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/range-diff.c b/range-diff.c
index 8a2dcbee32..ca449a0769 100644
--- a/range-diff.c
+++ b/range-diff.c
@@ -325,13 +325,24 @@ static int diffsize(const char *a, const char *b)
}
static void get_correspondences(struct string_list *a, struct string_list *b,
- int creation_factor)
+ int creation_factor, size_t max_memory)
{
int n = a->nr + b->nr;
int *cost, c, *a2b, *b2a;
int i, j;
-
- ALLOC_ARRAY(cost, st_mult(n, n));
+ size_t cost_size = st_mult(n, n);
+ size_t cost_bytes = st_mult(sizeof(int), cost_size);
+ if (cost_bytes >= max_memory) {
+ struct strbuf cost_str = STRBUF_INIT;
+ struct strbuf max_str = STRBUF_INIT;
+ strbuf_humanise_bytes(&cost_str, cost_bytes);
+ strbuf_humanise_bytes(&max_str, max_memory);
+ die(_("range-diff: unable to compute the range-diff, since it "
+ "exceeds the maximum memory for the cost matrix: %s "
+ "(%"PRIuMAX" bytes) needed, limited to %s (%"PRIuMAX" bytes)"),
+ cost_str.buf, (uintmax_t)cost_bytes, max_str.buf, (uintmax_t)max_memory);
+ }
+ ALLOC_ARRAY(cost, cost_size);
ALLOC_ARRAY(a2b, n);
ALLOC_ARRAY(b2a, n);
@@ -591,7 +602,8 @@ int show_range_diff(const char *range1, const char *range2,
if (!res) {
find_exact_matches(&branch1, &branch2);
get_correspondences(&branch1, &branch2,
- range_diff_opts->creation_factor);
+ range_diff_opts->creation_factor,
+ range_diff_opts->max_memory);
output(&branch1, &branch2, range_diff_opts);
}