Skip to content

Commit 5fb47c2

Browse files
committed
Improve MinHeap implementation
Migrated to a new algorithm that does not go beyond the array, thus de-optimization of this piece of code is not happening
1 parent 64983aa commit 5fb47c2

File tree

1 file changed

+44
-45
lines changed

1 file changed

+44
-45
lines changed

packages/scheduler/src/SchedulerMinHeap.js

Lines changed: 44 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,72 +20,71 @@ export function push(heap: Heap, node: Node): void {
2020
}
2121

2222
export function peek(heap: Heap): Node | null {
23-
const first = heap[0];
24-
return first === undefined ? null : first;
23+
return heap.length === 0 ? null : heap[0];
2524
}
2625

2726
export function pop(heap: Heap): Node | null {
28-
const first = heap[0];
29-
if (first !== undefined) {
30-
const last = heap.pop();
31-
if (last !== first) {
32-
heap[0] = last;
33-
siftDown(heap, last, 0);
34-
}
35-
return first;
36-
} else {
27+
if (heap.length === 0) {
3728
return null;
3829
}
30+
const first = heap[0];
31+
32+
const last = heap.pop();
33+
34+
if (last !== first) {
35+
heap[0] = last;
36+
siftDown(heap, last, 0);
37+
}
38+
39+
return first;
3940
}
4041

4142
function siftUp(heap, node, i) {
4243
let index = i;
43-
while (true) {
44+
45+
while (index > 0) {
4446
const parentIndex = (index - 1) >>> 1;
4547
const parent = heap[parentIndex];
46-
if (parent !== undefined && compare(parent, node) > 0) {
47-
// The parent is larger. Swap positions.
48-
heap[parentIndex] = node;
49-
heap[index] = parent;
50-
index = parentIndex;
51-
} else {
52-
// The parent is smaller. Exit.
53-
return;
48+
49+
if (compare(parent, node) < 0) {
50+
break;
5451
}
52+
swap(heap, parentIndex, index);
53+
index = parentIndex;
5554
}
5655
}
5756

5857
function siftDown(heap, node, i) {
5958
let index = i;
60-
const length = heap.length;
61-
while (index < length) {
62-
const leftIndex = (index + 1) * 2 - 1;
63-
const left = heap[leftIndex];
64-
const rightIndex = leftIndex + 1;
65-
const right = heap[rightIndex];
66-
67-
// If the left or right node is smaller, swap with the smaller of those.
68-
if (left !== undefined && compare(left, node) < 0) {
69-
if (right !== undefined && compare(right, left) < 0) {
70-
heap[index] = right;
71-
heap[rightIndex] = node;
72-
index = rightIndex;
73-
} else {
74-
heap[index] = left;
75-
heap[leftIndex] = node;
76-
index = leftIndex;
77-
}
78-
} else if (right !== undefined && compare(right, node) < 0) {
79-
heap[index] = right;
80-
heap[rightIndex] = node;
81-
index = rightIndex;
82-
} else {
83-
// Neither child is smaller. Exit.
84-
return;
59+
const halfLength = heap.length >>> 1;
60+
61+
while (index < halfLength) {
62+
let bestIndex = index * 2 + 1;
63+
const rightIndex = index * 2 + 2;
64+
65+
// If the right node is smaller, swap with the smaller of those.
66+
if (
67+
heap.length > rightIndex &&
68+
compare(heap[rightIndex], heap[bestIndex]) < 0
69+
) {
70+
bestIndex = rightIndex;
71+
}
72+
73+
if (compare(node, heap[bestIndex]) < 0) {
74+
break;
8575
}
76+
77+
swap(heap, bestIndex, index);
78+
index = bestIndex;
8679
}
8780
}
8881

82+
function swap(heap, left, right) {
83+
const item = heap[left];
84+
heap[left] = heap[right];
85+
heap[right] = item;
86+
}
87+
8988
function compare(a, b) {
9089
// Compare sort index first, then task id.
9190
const diff = a.sortIndex - b.sortIndex;

0 commit comments

Comments
 (0)