Repository navigation
remote: use deques for the RPC call queues, fixes #10450 - #10454
Merged
ThomasWaldmann merged 1 commit intoSep 28, 2026
Merged
Conversation
RemoteRepository.call_many took the next call from the front of a list (calls.pop(0), self.preload_ids.pop(0)), which moves all the remaining entries each time. For a single item with millions of chunks (preload + get_many over all of its chunk ids), that made extract from a remote repository quadratic in the chunk count of the item. Use collections.deque with popleft() for calls, waiting_for and preload_ids. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 1.4-maint #10454 +/- ##
=============================================
- Coverage 82.13% 82.09% -0.04%
=============================================
Files 38 38
Lines 11478 11479 +1
Branches 1808 1808
=============================================
- Hits 9427 9424 -3
- Misses 1466 1469 +3
- Partials 585 586 +1 ☔ View full report in Codecov by Harness. |
ThomasWaldmann
added a commit
that referenced
this pull request
Sep 28, 2026
RemoteRepository.call_many took the next call from the front of a list (calls.pop(0), self.preload_ids.pop(0)), which moves all the remaining entries each time. For a single item with millions of chunks (preload + get_many over all of its chunk ids), that made extract from a remote repository quadratic in the chunk count of the item. Use collections.deque with popleft() for calls, waiting_for and preload_ids. Backport of #10454. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #10450 (1.4-maint).
RemoteRepository.call_manytook the next call from the front of a list (calls.pop(0),self.preload_ids.pop(0)). Each of these moves all remaining entries. For a single item with millions of chunks (preload of all its chunk ids +get_manyover them), extract from a remote repository was therefore quadratic in the chunk count of that item.This PR uses
collections.dequewithpopleft()forcalls,waiting_forandpreload_ids.preload_idsis fed bypreload()for every item, so reversing the list (to pop from the end) would need a prepend per item, which is quadratic too. A deque avoids that.Measurements
Measured on a Ryzen 5 8500GE (Zen 4), Python 3.13,
repokey-blake2, lz4. The archive has one stdin item of N unique 4 KiB chunks (fixed,4096). The data compresses to almost nothing, so the times show per-chunk cost. The command isborg extract --stdout ::a big. For remote runs the repo isssh://__testsuite__/...(borg serveover pipes).With this PR, remote extract is linear at about 15.5 µs per chunk up to 12.3 M chunks, the size from the issue. Peak RSS does not change.
On master, borg2's own repository access has no such lists. The
calls.pop(0)inlegacy/remote.pyis only reached viaborg transfer --from-borg1 --chunker-paramsfrom a remote borg 1.x repo. This PR does not cover that path.Tests
pytest src/borg/testsuite/remote.py src/borg/testsuite/archiver.py -k "Remote or remote": 255 passed, 22 skipped.🤖 Generated with Claude Code