Turbopack: Cache canonicalized paths without turbo-tasks, try to find the longest cached prefix first (#99270)
When converting from an absolute system path to a filesystem-relative
path, we'd first try to lexically `strip_prefix`, but if that failed,
we'd fall back to trying to canonicalize the root path before stripping.
Because we don't know how many of the path segments refer to the root,
we have to canonicalize one path segment at a time.
With turbo-tasks, we have to probe the cache once per path segment,
starting from the shortest possible path segment.
This removes the `turbo_tasks::function` we were using to cache the
canonicalization calls, and instead stores caches in `BTreeMap`s. This
lets us efficiently look up the longest matching prefix in the cache,
which (in the happy path) should be a match for a filesystem root.
## Possible concerns
- ~We have duplicated canonicalization caches, one for the map, one for
each `DiskFileSystem`. Would a per-process (`OnceLock`) cache of
canonicalization calls make more sense?~ We now prefer lookups in the
map, which effectively solves this.
- A `PatriciaMap` would likely be more space efficient. `PatriciaMap` is
currently only used in `AliasMap`:
https://github.com/vercel/next.js/blob/ff6ac752af572467f35187e421dd7e558797b412/turbopack/crates/turbopack-core/src/resolve/alias_map.rs#L16
## Things I don't think are concerns
- `RwLock`: If we have a lot of writes, that means we're spending a lot
of time doing canonicalization, which would be a bigger problem than
locking.