Commit c13f15d
committed
reftable: fix quadratic behavior in the presence of tombstones
When many tombstones are present in a reftable, operations that need
to look up or iterate over refs exhibit quadratic behavior. With
8000 refs deleted and re-created, update-ref takes ~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 any code path that seeks into a range containing
tombstones, including:
- 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 no longer setting suppress_deletions on the stack's
merged table 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.
The suppress_deletions flag and its logic in the merged iterator are
retained for downstream users of the reftable library (e.g. libgit2).
This also requires adding deletion checks to the log iteration paths,
since suppress_deletions applied to both ref and log iterators.
Both tests in p1401 go from ~14s to ~0.2s with this change.
Reported-by: Jeff King <peff@peff.net>
Signed-off-by: Kristofer Karlsson <krka@spotify.com>1 parent 889d0d3 commit c13f15d
2 files changed
Lines changed: 43 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
84 | 84 | | |
85 | 85 | | |
86 | 86 | | |
87 | | - | |
| 87 | + | |
| 88 | + | |
88 | 89 | | |
89 | 90 | | |
90 | 91 | | |
| |||
110 | 111 | | |
111 | 112 | | |
112 | 113 | | |
113 | | - | |
114 | 114 | | |
115 | 115 | | |
116 | 116 | | |
| |||
652 | 652 | | |
653 | 653 | | |
654 | 654 | | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
655 | 658 | | |
656 | 659 | | |
657 | 660 | | |
| |||
1532 | 1535 | | |
1533 | 1536 | | |
1534 | 1537 | | |
| 1538 | + | |
| 1539 | + | |
1535 | 1540 | | |
1536 | 1541 | | |
1537 | 1542 | | |
| |||
1929 | 1934 | | |
1930 | 1935 | | |
1931 | 1936 | | |
| 1937 | + | |
| 1938 | + | |
1932 | 1939 | | |
1933 | 1940 | | |
1934 | 1941 | | |
| |||
2061 | 2068 | | |
2062 | 2069 | | |
2063 | 2070 | | |
| 2071 | + | |
| 2072 | + | |
| 2073 | + | |
2064 | 2074 | | |
2065 | 2075 | | |
2066 | 2076 | | |
| |||
2220 | 2230 | | |
2221 | 2231 | | |
2222 | 2232 | | |
| 2233 | + | |
| 2234 | + | |
2223 | 2235 | | |
2224 | 2236 | | |
2225 | 2237 | | |
| |||
2272 | 2284 | | |
2273 | 2285 | | |
2274 | 2286 | | |
| 2287 | + | |
| 2288 | + | |
| 2289 | + | |
| 2290 | + | |
2275 | 2291 | | |
2276 | 2292 | | |
2277 | 2293 | | |
| |||
2318 | 2334 | | |
2319 | 2335 | | |
2320 | 2336 | | |
2321 | | - | |
2322 | | - | |
| 2337 | + | |
| 2338 | + | |
2323 | 2339 | | |
2324 | | - | |
2325 | | - | |
2326 | | - | |
2327 | | - | |
2328 | | - | |
2329 | | - | |
| 2340 | + | |
| 2341 | + | |
| 2342 | + | |
| 2343 | + | |
| 2344 | + | |
| 2345 | + | |
| 2346 | + | |
| 2347 | + | |
| 2348 | + | |
| 2349 | + | |
| 2350 | + | |
| 2351 | + | |
| 2352 | + | |
| 2353 | + | |
2330 | 2354 | | |
2331 | 2355 | | |
2332 | | - | |
| 2356 | + | |
2333 | 2357 | | |
2334 | 2358 | | |
2335 | 2359 | | |
| |||
2442 | 2466 | | |
2443 | 2467 | | |
2444 | 2468 | | |
| 2469 | + | |
| 2470 | + | |
2445 | 2471 | | |
2446 | 2472 | | |
2447 | 2473 | | |
| |||
2625 | 2651 | | |
2626 | 2652 | | |
2627 | 2653 | | |
| 2654 | + | |
| 2655 | + | |
| 2656 | + | |
| 2657 | + | |
2628 | 2658 | | |
2629 | 2659 | | |
2630 | 2660 | | |
| |||
2791 | 2821 | | |
2792 | 2822 | | |
2793 | 2823 | | |
| 2824 | + | |
| 2825 | + | |
2794 | 2826 | | |
2795 | 2827 | | |
2796 | 2828 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
337 | 337 | | |
338 | 338 | | |
339 | 339 | | |
340 | | - | |
341 | 340 | | |
342 | 341 | | |
343 | 342 | | |
| |||
0 commit comments