From: "Kristofer Karlsson via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "René Scharfe" <l.s.r@web.de>,
"Kristofer Karlsson" <krka@spotify.com>,
"Kristofer Karlsson" <krka@spotify.com>,
"Kristofer Karlsson" <krka@spotify.com>
Subject: [PATCH v3 2/2] prio-queue: use cascade for unfused gets
Date: Wed, 08 Jul 2026 17:49:48 +0000 [thread overview]
Message-ID: <89a22c6a7532afa530f1c04ee27177e141dd360c.1783532989.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2132.v3.git.1783532989.gitgitgadget@gmail.com>
From: Kristofer Karlsson <krka@spotify.com>
When flush_get() removes the root without an immediate replacement,
use a cascade-then-sift-up strategy instead of sift-down.
Standard sift-down places the last element at the root and sifts it
down. This needs two comparisons per level (pick the smaller child,
then compare against the element), even though the displaced element
almost always ends up near the bottom where it came from.
cascade_down() instead moves the vacancy down by promoting the
smaller child at each level (one comparison per level), leaving the
vacancy at a leaf. The last element is then placed at the vacancy
and sift_up() floats it to its correct position, which is typically
very little work since it already belongs near the bottom.
This is the well-known "bottom-up" variant of sift-down [1].
[1] https://en.wikipedia.org/wiki/Heapsort#Bottom-up_heapsort
Helped-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Kristofer Karlsson <krka@spotify.com>
---
prio-queue.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/prio-queue.c b/prio-queue.c
index 926fc04e85..230d6f5e33 100644
--- a/prio-queue.c
+++ b/prio-queue.c
@@ -66,13 +66,31 @@ static void sift_down_root(struct prio_queue *queue)
}
}
+/* Cascade vacancy toward a leaf, promoting the smaller child at each level */
+static size_t cascade_down(struct prio_queue *queue)
+{
+ size_t ix, child;
+
+ for (ix = 0; (child = ix * 2 + 1) < queue->nr_; ix = child) {
+ if (child + 1 < queue->nr_ &&
+ compare(queue, child, child + 1) >= 0)
+ child++;
+ queue->array[ix] = queue->array[child];
+ }
+ return ix;
+}
+
static inline void flush_get(struct prio_queue *queue)
{
+ size_t ix;
+
if (!queue->get_pending)
return;
queue->get_pending = 0;
- queue->array[0] = queue->array[--queue->nr_];
- sift_down_root(queue);
+ --queue->nr_;
+ ix = cascade_down(queue);
+ queue->array[ix] = queue->array[queue->nr_];
+ sift_up(queue, ix);
}
void prio_queue_put(struct prio_queue *queue, void *thing)
--
gitgitgadget
next prev parent reply other threads:[~2026-07-08 17:49 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-31 17:57 [PATCH] prio-queue: use cascade-down sift for faster extract-min Kristofer Karlsson via GitGitGadget
2026-06-01 0:09 ` Junio C Hamano
2026-06-01 6:16 ` Junio C Hamano
2026-06-01 6:21 ` Kristofer Karlsson
2026-06-01 8:17 ` [PATCH v2] prio-queue: use cascade-down " Kristofer Karlsson via GitGitGadget
2026-06-02 16:36 ` René Scharfe
2026-06-02 22:40 ` Kristofer Karlsson
2026-06-05 20:39 ` Kristofer Karlsson
2026-06-07 7:30 ` René Scharfe
2026-06-07 12:07 ` Kristofer Karlsson
2026-06-29 21:16 ` Junio C Hamano
2026-06-08 11:56 ` Junio C Hamano
2026-07-06 21:52 ` Kristofer Karlsson
2026-07-08 10:43 ` René Scharfe
2026-07-08 10:59 ` Kristofer Karlsson
2026-07-08 11:55 ` René Scharfe
2026-07-08 12:44 ` Kristofer Karlsson
2026-07-08 17:49 ` [PATCH v3 0/2] prio-queue: use bottom-up sift for extract-min Kristofer Karlsson via GitGitGadget
2026-07-08 17:49 ` [PATCH v3 1/2] prio-queue: extract sift_up() from prio_queue_put() Kristofer Karlsson via GitGitGadget
2026-07-08 17:49 ` Kristofer Karlsson via GitGitGadget [this message]
2026-07-10 16:37 ` [PATCH v3 2/2] prio-queue: use cascade for unfused gets René Scharfe
2026-07-10 17:28 ` Kristofer Karlsson
2026-07-10 16:37 ` [PATCH v3 0/2] prio-queue: use bottom-up sift for extract-min René Scharfe
2026-07-10 17:40 ` Kristofer Karlsson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=89a22c6a7532afa530f1c04ee27177e141dd360c.1783532989.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=krka@spotify.com \
--cc=l.s.r@web.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox