You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
reftable: fix quadratic behavior when re-creating deleted refs
When many refs are deleted and then re-created, update-ref exhibits
quadratic behavior. With 8000 refs deleted and re-created, the
runtime is ~15s, quadrupling for each doubling of input size.
The root cause is the merged iterator's suppress_deletions flag.
When set, merged_iter_next_void() silently consumes tombstone records
in a tight internal loop before returning to the caller. This
prevents higher-level code from checking iteration bounds (such as
prefix or refname comparisons) until after all tombstones have been
scanned.
This affects two code paths during ref creation:
- refs_verify_refnames_available() seeks to "refs/tags/foo-1/" to
check for D/F conflicts and must scan through all subsequent
tombstones before the caller can see that they are past the prefix
of interest.
- reftable_backend_read_ref() seeks to a specific refname and must
scan through all subsequent tombstones before returning "not
found", because the merged iterator skips the matching tombstone
and searches for the next live record.
Fix this by removing suppress_deletions from the merged iterator and
instead handling deletion records at each call site in the reftable
backend, where prefix and refname bounds are available. Tombstones
are now returned to callers, which skip them after their existing
bounds checks. This allows iteration to terminate as soon as a
tombstone past the relevant bound is encountered.
This also requires adding deletion checks to the log iteration paths,
since suppress_deletions applied to both ref and log iterators.
Before:
nr=1000 0.306s
nr=2000 0.945s
nr=4000 3.816s
nr=8000 14.93s
After:
nr=1000 0.020s
nr=2000 0.044s
nr=4000 0.071s
nr=8000 0.145s
nr=16000 0.258s
nr=32000 0.591s
Reported-by: Jeff King <peff@peff.net>
Signed-off-by: Kristofer Karlsson <krka@spotify.com>
0 commit comments