Conversation
Member
|
I suggest that you reuse cat_ranges - this will join a number of requests based on heuristics for maximum read size, and submit them concurrently for backends that support it. |
BlockCache takes an optional multi_fetcher, as MMapCache does, and hands it all runs of missing blocks in one call. AbstractBufferedFile supplies one backed by fs.cat_ranges for blockcache on async filesystems, so the runs are requested concurrently. Sync filesystems keep calling fetcher once per run: their default cat_ranges reopens the file for each range.
itzzdev09
force-pushed
the
blockcache-coalesce-fetches
branch
from
September 29, 2026 04:41
cc11165 to
3fbd8a6
Compare
Contributor
Author
|
Done in 3fbd8a6: |
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.
Closes the second half of #1960. The duplicate download reported there is gone (#1984, #2150), but the other complaint in the thread still holds: a large read costs one serialized request per block.
That is 40 requests on
master, one per 5 MiB block, each waiting for the last. With this change it is 2, for the same 200 MiB of data: the blocks the cache does not hold are fetched in contiguous runs.The old loop had a note on it:
The obstacle was
functools.lru_cache, which cannot say whether a block is held and cannot be given a value fetched elsewhere.BackgroundBlockCachealready usesUpdatableLRUfrom this module, which hasis_key_cachedandadd_key, soBlockCachenow uses it too._fetch_blockswalks the requested range, takes what is cached and groups the rest into runs; each run is onefetchercall whose blocks are then added to the LRU individually, so eviction stays per block, exactly as before.A run is capped at
maxblocks. Without the cap a single read could both ask a backend for an unbounded range and evict its own earlier blocks before they were read, which is the regression #1984 fixed.Behaviour that does not change: block boundaries and sizes, what ends up cached, LRU eviction order,
cache_info(),hit_count,miss_count,total_requested_bytes, and pickling. A cached or single-block read still goes through the ordinary path.UpdatableLRU.add_keytakes a new keyword-onlycount_miss=False, so a caller that fetched the value itself can still have it counted as a miss.BackgroundBlockCacheis untouched.Tests
Four new tests in
test_caches.py: one request for a run of eight missing blocks; only the gaps fetched when some blocks are already held; a run split atmaxblocks; and a run stopping at the end of the file. All four fail onmaster.fsspec/tests/plustest_cached.py: 856 passed, 235 skipped, 2 xfailed.