Skip to content

Commit

Permalink
Sort jobs by number of dependencies. (#251)
Browse files Browse the repository at this point in the history
Hopefully this improves compilecache reuse.
  • Loading branch information
maleadt authored Jan 10, 2024
1 parent 1a79629 commit 6c3a9f8
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/evaluate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -899,8 +899,17 @@ function evaluate(configs::Vector{Configuration}, packages::Vector{Package}=Pack
end
push!(jobs, job)
end
## use a random test order to (hopefully) get a more reasonable ETA
shuffle!(jobs)

# sort the jobs
try
# ... by number of dependencies, hopefully increasing cache reuse
deps = package_dependencies(first(values(configs)))
ndeps(pkg) = haskey(deps, pkg.name) ? length(deps[pkg.name]) : typemax(Int)
sort!(jobs, by=job->ndeps(job.package))
catch err
@error "Could not sort jobs" exception=(err, catch_backtrace())
shuffle!(jobs)
end

# pre-filter the jobs for packages we'll skip to get a better ETA
jobs = filter(jobs) do job
Expand Down
56 changes: 56 additions & 0 deletions src/registry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,62 @@ function _get_packages(config::Configuration)
return packages
end

"""
package_dependencies(config; transitive=true)
This function returns a dictionary of package dependencies for each package in the registry.
## Arguments
- `config`: The configuration object for the registry.
- `transitive`: A boolean indicating whether to include transitive dependencies. Default is `true`.
## Returns
A dictionary where the keys are package names and the values are vectors of package names representing the dependencies.
"""
function package_dependencies(config; transitive=true)
dependencies = Dict{String,Vector{String}}()

# iterate packages from the registry
registry = get_registry(config)
registry_instance = Pkg.Registry.RegistryInstance(registry)
for (_, pkg) in registry_instance
# we only consider the latest version of each package; see `get_packages`
info = Pkg.Registry.registry_info(pkg)
version = maximum(keys(info.version_info))

# iterate the dependencies
pkg_deps = Set{String}()
for (version_range, deps) in info.deps
version in version_range || continue
for (name, uuid) in deps
push!(pkg_deps, name)
end
end
delete!(pkg_deps, "julia")
dependencies[pkg.name] = collect(pkg_deps)
end

if transitive
function get_deps!(pkg, deps_seen=String[])
new_deps = get(dependencies, pkg, [])
for dep in new_deps
if !(dep in deps_seen)
push!(deps_seen, dep)
get_deps!(dep, deps_seen)
end
end
return deps_seen
end

for (pkg, deps) in dependencies
dependencies[pkg] = get_deps!(pkg)
end
end

return dependencies
end

# look up the tree hash of a package/slug combination.
# this is useful for verifying the package store on disk.
# returns nothing if the combination wasn't found in the registry.
Expand Down

0 comments on commit 6c3a9f8

Please sign in to comment.