]> git.ipfire.org Git - thirdparty/git.git/commitdiff
reftable/merged: avoid duplicate pqueue emptiness check
authorPatrick Steinhardt <ps@pks.im>
Mon, 4 Mar 2024 10:49:18 +0000 (11:49 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 4 Mar 2024 18:19:40 +0000 (10:19 -0800)
When calling `merged_iter_next_void()` we first check whether the iter
has been exhausted already. We already perform this check two levels
down the stack in `merged_iter_next_entry()` though, which makes this
check redundant.

Now if this check was there to accelerate the common case it might have
made sense to keep it. But the iterator being exhausted is rather the
uncommon case because you can expect most reftable stacks to contain
more than two refs.

Simplify the code by removing the check. As `merged_iter_next_void()` is
basically empty except for calling `merged_iter_next()` now, merge these
two functions. This also results in a tiny speedup when iterating over
many refs:

    Benchmark 1: show-ref: single matching ref (revision = HEAD~)
      Time (mean ± σ):     125.6 ms ±   3.8 ms    [User: 122.7 ms, System: 2.8 ms]
      Range (min … max):   122.4 ms … 153.4 ms    1000 runs

    Benchmark 2: show-ref: single matching ref (revision = HEAD)
      Time (mean ± σ):     124.0 ms ±   3.9 ms    [User: 121.1 ms, System: 2.8 ms]
      Range (min … max):   120.1 ms … 156.4 ms    1000 runs

    Summary
      show-ref: single matching ref (revision = HEAD) ran
        1.01 ± 0.04 times faster than show-ref: single matching ref (revision = HEAD~)

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
reftable/merged.c

index 29161a32cfa42876744c0b534bd6ce5f1ab21102..f85a24c6786c6fb8e102ffc9ceb35f23706c8c9b 100644 (file)
@@ -148,27 +148,19 @@ static int merged_iter_next_entry(struct merged_iter *mi,
        return 0;
 }
 
-static int merged_iter_next(struct merged_iter *mi, struct reftable_record *rec)
+static int merged_iter_next_void(void *p, struct reftable_record *rec)
 {
+       struct merged_iter *mi = p;
        while (1) {
                int err = merged_iter_next_entry(mi, rec);
-               if (err == 0 && mi->suppress_deletions &&
-                   reftable_record_is_deletion(rec)) {
+               if (err)
+                       return err;
+               if (mi->suppress_deletions && reftable_record_is_deletion(rec))
                        continue;
-               }
-
-               return err;
+               return 0;
        }
 }
 
-static int merged_iter_next_void(void *p, struct reftable_record *rec)
-{
-       struct merged_iter *mi = p;
-       if (merged_iter_pqueue_is_empty(mi->pq) && mi->advance_index < 0)
-               return 1;
-       return merged_iter_next(mi, rec);
-}
-
 static struct reftable_iterator_vtable merged_iter_vtable = {
        .next = &merged_iter_next_void,
        .close = &merged_iter_close,