From c6ca0cd509d4c84cc28d320bb61734bc33f2261d Mon Sep 17 00:00:00 2001
From: ChangAo Chen <cca5507@qq.com>
Date: Tue, 29 Oct 2024 11:06:53 +0800
Subject: [PATCH v2] Reduce one comparison in binaryheap's sift down

---
 src/common/binaryheap.c | 42 ++++++++++++++++++++---------------------
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/src/common/binaryheap.c b/src/common/binaryheap.c
index 7377ebdf15..e186dae342 100644
--- a/src/common/binaryheap.c
+++ b/src/common/binaryheap.c
@@ -323,42 +323,40 @@ sift_down(binaryheap *heap, int node_off)
 	{
 		int			left_off = left_offset(node_off);
 		int			right_off = right_offset(node_off);
-		int			swap_off = 0;
+		/* Assume the left child is the larger one */
+		int			larger_off = left_off;
 
-		/* Is the left child larger than the parent? */
-		if (left_off < heap->bh_size &&
-			heap->bh_compare(node_val,
-							 heap->bh_nodes[left_off],
-							 heap->bh_arg) < 0)
-			swap_off = left_off;
+		Assert(left_off > 0 && left_off < right_off);
+
+		/* If we have no children, we're done */
+		if (left_off >= heap->bh_size)
+			break;
 
-		/* Is the right child larger than the parent? */
+		/*
+		 * Now we have the left child at least. If we have the right
+		 * child, we compare the two children to get the larger one.
+		 */
 		if (right_off < heap->bh_size &&
-			heap->bh_compare(node_val,
+			heap->bh_compare(heap->bh_nodes[left_off],
 							 heap->bh_nodes[right_off],
 							 heap->bh_arg) < 0)
-		{
-			/* swap with the larger child */
-			if (!swap_off ||
-				heap->bh_compare(heap->bh_nodes[left_off],
-								 heap->bh_nodes[right_off],
-								 heap->bh_arg) < 0)
-				swap_off = right_off;
-		}
+			larger_off = right_off;
 
 		/*
-		 * If we didn't find anything to swap, the heap condition is
-		 * satisfied, and we're done.
+		 * If the larger child is less than or equal to the
+		 * parent, we're done.
 		 */
-		if (!swap_off)
+		if (heap->bh_compare(node_val,
+							 heap->bh_nodes[larger_off],
+							 heap->bh_arg) >= 0)
 			break;
 
 		/*
 		 * Otherwise, swap the hole with the child that violates the heap
 		 * property; then go on to check its children.
 		 */
-		heap->bh_nodes[node_off] = heap->bh_nodes[swap_off];
-		node_off = swap_off;
+		heap->bh_nodes[node_off] = heap->bh_nodes[larger_off];
+		node_off = larger_off;
 	}
 	/* Re-fill the hole */
 	heap->bh_nodes[node_off] = node_val;
-- 
2.39.3 (Apple Git-146)

