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
Opening a cloud collection: stop paying a round trip per folder
Two findings, both classification rather than algorithm.
**A File-Provider folder was being walked as if it were local.**
`ResumableTreeWalk` already knows it is latency-bound — a source declares how
many listings it can usefully have in flight, `RemoteTreeSource` says six, and
the default is one because a real directory listing is a syscall over a warm
cache that gains nothing from overlapping. A vault on iCloud Drive, Dropbox or
any other Files provider has a *file path*, so it reaches `LocalTreeSource` and
inherited that serial default — but every listing there is an XPC round trip
into the provider's extension, and a network fetch behind it for a folder not
yet enumerated. N folders, N latencies, end to end. That is where the minutes
were.
`LocalTreeSource` now reports six for a provider-backed root, detected by path
(`/Library/Mobile Documents/`, `/Library/CloudStorage/`) rather than by asking
the coordinator — the question is asked once per scan and must not itself be a
round trip. An ordinary folder still reports one, which matters: routing width-1
through the concurrency window once made the local walk about four times slower,
which is why `theWalkIsCompetitiveWithTheEnumeratorOnARealisticVault` exists. A
test measures the overlap on a synthetic tree with a provider's latency profile.
**The direct-API path listed one folder at a time when it did not have to.**
Six in flight is still N/6 round trips for N folders, and every provider can
return a whole subtree in paginated batches — Dropbox `list_folder` with
`recursive: true`, Graph `/delta`, Drive's folder query, Box recursed
server-side. Dropbox's was already implemented and already in use: it is how
`changes(since: nil,)` obtains its cursor. The initial open simply never asked
for it.
`RemoteStore.listRecursively` is that call, defaulting to nil so a provider
gains it one at a time and nothing regresses meanwhile. `RecursiveListingCache`
fetches once and answers every `children(of:)` from memory.
Deliberately a cache rather than a replacement for the walk: building the tree
straight from a recursive listing would discard checkpointing, incremental
publishing, per-directory fault isolation and resumption, all of which are worth
more on a large interrupted sync than the walk's own bookkeeping costs. The walk
is untouched; only its expensive step is made free. Measured: twenty folders
cost twenty-one listings before and one recursive request after, finding the
same hundred files.
472 app tests, 408 editor.
Co-Authored-By: Claude <claude-opus-5> <noreply@anthropic.com>
0 commit comments