mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
array.c: replace recursive heapify with iterative implementation
Eliminates stack overflow risk on memory-constrained devices by reducing stack usage from O(log n) to O(1) during heap sort operations. Co-authored-by: Atlassian Rovo Dev
This commit is contained in:
+22
-11
@@ -1844,20 +1844,31 @@ sort_cmp(mrb_state *mrb, mrb_value ary, mrb_value *p, mrb_int a, mrb_int b, mrb_
|
||||
static void
|
||||
heapify(mrb_state *mrb, mrb_value ary, mrb_value *a, mrb_int index, mrb_int size, mrb_value blk)
|
||||
{
|
||||
mrb_int max = index;
|
||||
mrb_int left_index = 2 * index + 1;
|
||||
mrb_int right_index = left_index + 1;
|
||||
if (left_index < size && sort_cmp(mrb, ary, a, left_index, max, blk)) {
|
||||
max = left_index;
|
||||
}
|
||||
if (right_index < size && sort_cmp(mrb, ary, a, right_index, max, blk)) {
|
||||
max = right_index;
|
||||
}
|
||||
if (max != index) {
|
||||
/* Iterative heapify to avoid stack overflow on memory-constrained devices */
|
||||
while (1) {
|
||||
mrb_int max = index;
|
||||
mrb_int left_index = 2 * index + 1;
|
||||
mrb_int right_index = left_index + 1;
|
||||
|
||||
if (left_index < size && sort_cmp(mrb, ary, a, left_index, max, blk)) {
|
||||
max = left_index;
|
||||
}
|
||||
if (right_index < size && sort_cmp(mrb, ary, a, right_index, max, blk)) {
|
||||
max = right_index;
|
||||
}
|
||||
|
||||
if (max == index) {
|
||||
/* Heap property satisfied, no more swaps needed */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Swap elements and continue heapifying down the affected subtree */
|
||||
mrb_value tmp = a[max];
|
||||
a[max] = a[index];
|
||||
a[index] = tmp;
|
||||
heapify(mrb, ary, a, max, size, blk);
|
||||
|
||||
/* Continue with the affected child subtree */
|
||||
index = max;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user