diff options
author | Junio C Hamano <gitster@pobox.com> | 2025-09-18 10:07:02 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2025-09-18 10:07:02 -0700 |
commit | 7b776bc308f904850f36a82e19f9775e672d464c (patch) | |
tree | 90f0638597e3c9be9360f3b35f5ac986dd9e7fa2 /range-diff.c | |
parent | 44c0d062bd2fed84ba1ac930a153de37a5280cd3 (diff) | |
parent | 00727249ec8404c68391ec58e9c9f0d8a88d5ca0 (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.c | 20 |
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); } |