Skip to content

Commit

Permalink
also cache identify_package and locate_package during package loa…
Browse files Browse the repository at this point in the history
…ding (#48247)
  • Loading branch information
KristofferC authored Jan 13, 2023
1 parent 4dad6d3 commit 29fbd1c
Showing 1 changed file with 69 additions and 19 deletions.
88 changes: 69 additions & 19 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,12 @@ struct LoadingCache
env_project_file::Dict{String, Union{Bool, String}}
project_file_manifest_path::Dict{String, Union{Nothing, String}}
require_parsed::Set{String}
identified_where::Dict{Tuple{PkgId, String}, Union{Nothing, Tuple{PkgId, Union{Nothing, String}}}}
identified::Dict{String, Union{Nothing, Tuple{PkgId, Union{Nothing, String}}}}
located::Dict{Tuple{PkgId, Union{String, Nothing}}, Union{String, Nothing}}
end
const LOADING_CACHE = Ref{Union{LoadingCache, Nothing}}(nothing)
LoadingCache() = LoadingCache(load_path(), Dict(), Dict(), Dict(), Set())
LoadingCache() = LoadingCache(load_path(), Dict(), Dict(), Dict(), Set(), Dict(), Dict(), Dict())


struct TOMLCache
Expand Down Expand Up @@ -311,22 +314,49 @@ is also returned.
"""
identify_package_env(where::Module, name::String) = identify_package_env(PkgId(where), name)
function identify_package_env(where::PkgId, name::String)
where.name === name && return where, nothing
where.uuid === nothing && return identify_package_env(name) # ignore `where`
for env in load_path()
pkgid = manifest_deps_get(env, where, name)
pkgid === nothing && continue # not found--keep looking
pkgid.uuid === nothing || return pkgid, env # found in explicit environment--use it
return nothing # found in implicit environment--return "not found"
cache = LOADING_CACHE[]
if cache !== nothing
pkg_env = get(cache.identified_where, (where, name), nothing)
pkg_env === nothing || return pkg_env
end
pkg_env = nothing
if where.name === name
pkg_env = where, nothing
elseif where.uuid === nothing
pkg_env = identify_package_env(name) # ignore `where`
else
for env in load_path()
pkgid = manifest_deps_get(env, where, name)
pkgid === nothing && continue # not found--keep looking
if pkgid.uuid !== nothing
pkg_env = pkgid, env # found in explicit environment--use it
end
break # found in implicit environment--return "not found"
end
end
return nothing
if cache !== nothing
cache.identified_where[(where, name)] = pkg_env
end
return pkg_env
end
function identify_package_env(name::String)
cache = LOADING_CACHE[]
if cache !== nothing
pkg_env = get(cache.identified, name, nothing)
pkg_env === nothing || return pkg_env
end
pkg_env = nothing
for env in load_path()
uuid = project_deps_get(env, name)
uuid === nothing || return uuid, env # found--return it
pkg = project_deps_get(env, name)
if pkg !== nothing
pkg_env = pkg, env # found--return it
break
end
end
return nothing
if cache !== nothing
cache.identified[name] = pkg_env
end
return pkg_env
end

_nothing_or_first(x) = x === nothing ? nothing : first(x)
Expand Down Expand Up @@ -376,6 +406,12 @@ julia> Base.locate_package(pkg)
```
"""
function locate_package(pkg::PkgId, stopenv::Union{String, Nothing}=nothing)::Union{Nothing,String}
cache = LOADING_CACHE[]
if cache !== nothing
path = get(cache.located, (pkg, stopenv), nothing)
path === nothing || return path
end
path = nothing
if pkg.uuid === nothing
for env in load_path()
# look for the toplevel pkg `pkg.name` in this entry
Expand All @@ -386,25 +422,39 @@ function locate_package(pkg::PkgId, stopenv::Union{String, Nothing}=nothing)::Un
# pkg.name is present in this directory or project file,
# return the path the entry point for the code, if it could be found
# otherwise, signal failure
return implicit_manifest_uuid_path(env, pkg)
path = implicit_manifest_uuid_path(env, pkg)
@goto done
end
end
stopenv == env && return nothing
stopenv == env && @goto done
end
else
for env in load_path()
path = manifest_uuid_path(env, pkg)
# missing is used as a sentinel to stop looking further down in envs
path === missing && return nothing
path === nothing || return entry_path(path, pkg.name)
if path === missing
path = nothing
@goto done
end
if path !== nothing
path = entry_path(path, pkg.name)
@goto done
end
stopenv == env && break
end
# Allow loading of stdlibs if the name/uuid are given
# e.g. if they have been explicitly added to the project/manifest
path = manifest_uuid_path(Sys.STDLIB, pkg)
path isa String && return entry_path(path, pkg.name)
mbypath = manifest_uuid_path(Sys.STDLIB, pkg)
if mbypath isa String
path = entry_path(mbypath, pkg.name)
@goto done
end
end
return nothing
@label done
if cache !== nothing
cache.located[(pkg, stopenv)] = path
end
return path
end

"""
Expand Down

0 comments on commit 29fbd1c

Please sign in to comment.