]> git.99rst.org Git - git.git/commit
prio-queue: fold lazy_queue into prio_queue for automatic get+put fusion
authorKristofer Karlsson <redacted>
Mon, 8 Jun 2026 19:10:51 +0000 (19:10 +0000)
committerJunio C Hamano <redacted>
Tue, 9 Jun 2026 18:11:46 +0000 (11:11 -0700)
commit9f75e7a150edfe931391047bf84c697b4b15c4c4
treec5f2edda78cc478d064cee80030913765722b248
parent3c5783698854b56376b775af5053ae6fbe825cc0
prio-queue: fold lazy_queue into prio_queue for automatic get+put fusion

Defer the actual removal in prio_queue_get() until the next
operation.  If that next operation is a prio_queue_put(), the
removal and insertion are fused into a single replace — writing
the new element at the root and sifting it down — which avoids
a full remove-rebalance-insert cycle.

This matches the dominant usage pattern in git's commit traversal:
get a commit, then put its parents.  The first parent insertion
after each get is now a replace operation automatically.

This generalizes the lazy_queue pattern from builtin/describe.c
(introduced in 08bb69d70f) into prio_queue itself.  Three callers
independently implemented the same get+put fusion:

  - builtin/describe.c had a full lazy_queue wrapper
  - commit.c:pop_most_recent_commit() used peek+replace
  - builtin/show-branch.c:join_revs() used peek+replace

All three now collapse to plain _get() and _put(), with the data
structure handling the fusion internally.  This simplifies callers
and means every prio_queue user gets the optimization for free
without needing to implement it manually.

Remove prio_queue_replace() since no external callers remain.

Benchmarked on a 1.8M-commit monorepo (30 interleaved runs,
paired t-test, Xeon @ 2.20GHz):

Code paths that previously did eager get+put (new optimization):

  Command                       base    patched  change      p
  merge-base --all A A~1000     3828ms  3725ms   -2.69%  0.0001
  rev-list --count A~1000..A    3055ms  2986ms   -2.27%  0.0601
  log --oneline A~1000..A       3408ms  3350ms   -1.71%  0.0482

Code paths that already had manual get+put fusion (expect
neutral — the optimization moves into prio_queue but the number
of heap operations stays the same):

  Command                       base    patched  change      p
  show-branch A A~1000          9156ms  9127ms   -0.32%  0.3470
  describe (4751 revs, 81K repo) 1983ms 1963ms  -1.02%  <0.001

No regressions in any scenario.

Suggested-by: René Scharfe <redacted>
Signed-off-by: Kristofer Karlsson <redacted>
Signed-off-by: Junio C Hamano <redacted>
builtin/describe.c
builtin/show-branch.c
commit.c
prio-queue.c
prio-queue.h
t/unit-tests/u-prio-queue.c
git clone https://git.99rst.org/PROJECT