Skip to content

Commit 694d59a

Browse files
KristofferCandreasnoack
authored andcommitted
add an LRU cache for precompile files (#32651)
instead of always clobbering the one precompile file per package for multiple environments, introduce a LRU cache (10 files that we cycle through).
1 parent 9da7fbc commit 694d59a

File tree

1 file changed

+34
-13
lines changed

1 file changed

+34
-13
lines changed

base/loading.jl

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -649,15 +649,22 @@ end
649649
cache_file_entry(pkg::PkgId) = joinpath(
650650
"compiled",
651651
"v$(VERSION.major).$(VERSION.minor)",
652-
pkg.uuid === nothing ? "$(pkg.name).ji" : joinpath(pkg.name, "$(package_slug(pkg.uuid)).ji")
653-
)
652+
pkg.uuid === nothing ? "" : pkg.name),
653+
pkg.uuid === nothing ? pkg.name : package_slug(pkg.uuid)
654654

655655
function find_all_in_cache_path(pkg::PkgId)
656656
paths = String[]
657-
entry = cache_file_entry(pkg)
658-
for depot in DEPOT_PATH
659-
path = joinpath(depot, entry)
660-
isfile_casesensitive(path) && push!(paths, path)
657+
entrypath, entryfile = cache_file_entry(pkg)
658+
for path in joinpath.(DEPOT_PATH, entrypath)
659+
isdir(path) || continue
660+
for file in readdir(path)
661+
if !((pkg.uuid === nothing && file == entryfile * ".ji") ||
662+
(pkg.uuid !== nothing && startswith(file, entryfile * "_")))
663+
continue
664+
end
665+
filepath = joinpath(path, file)
666+
isfile_casesensitive(filepath) && push!(paths, filepath)
667+
end
661668
end
662669
return paths
663670
end
@@ -746,6 +753,10 @@ function _require_search_from_serialized(pkg::PkgId, sourcepath::String)
746753
if staledeps === true
747754
continue
748755
end
756+
try
757+
touch(path_to_try) # update timestamp of precompilation file
758+
catch # file might be read-only and then we fail to update timestamp, which is fine
759+
end
749760
# finish loading module graph into staledeps
750761
for i in 1:length(staledeps)
751762
dep = staledeps[i]
@@ -1222,11 +1233,25 @@ function compilecache(pkg::PkgId)
12221233
path === nothing && throw(ArgumentError("$pkg not found during precompilation"))
12231234
return compilecache(pkg, path)
12241235
end
1236+
1237+
const MAX_NUM_PRECOMPILE_FILES = 10
1238+
12251239
function compilecache(pkg::PkgId, path::String)
12261240
# decide where to put the resulting cache file
1227-
cachefile = abspath(DEPOT_PATH[1], cache_file_entry(pkg))
1228-
cachepath = dirname(cachefile)
1241+
entrypath, entryfile = cache_file_entry(pkg)
1242+
cachepath = joinpath(DEPOT_PATH[1], entrypath)
12291243
isdir(cachepath) || mkpath(cachepath)
1244+
if pkg.uuid === nothing
1245+
cachefile = abspath(cachepath, entryfile) * ".ji"
1246+
else
1247+
candidates = filter!(x -> startswith(x, entryfile * "_"), readdir(cachepath))
1248+
if length(candidates) >= MAX_NUM_PRECOMPILE_FILES
1249+
idx = findmin(mtime.(joinpath.(cachepath, candidates)))[2]
1250+
rm(joinpath(cachepath, candidates[idx]))
1251+
end
1252+
project_precompile_slug = slug(_crc32c(something(Base.active_project(), "")), 5)
1253+
cachefile = abspath(cachepath, string(entryfile, "_", project_precompile_slug, ".ji"))
1254+
end
12301255
# build up the list of modules that we want the precompile process to preserve
12311256
concrete_deps = copy(_concrete_dependencies)
12321257
for (key, mod) in loaded_modules
@@ -1236,11 +1261,7 @@ function compilecache(pkg::PkgId, path::String)
12361261
end
12371262
# run the expression and cache the result
12381263
verbosity = isinteractive() ? CoreLogging.Info : CoreLogging.Debug
1239-
if isfile(cachefile)
1240-
@logmsg verbosity "Recompiling stale cache file $cachefile for $pkg"
1241-
else
1242-
@logmsg verbosity "Precompiling $pkg"
1243-
end
1264+
@logmsg verbosity "Precompiling $pkg"
12441265
p = create_expr_cache(path, cachefile, concrete_deps, pkg.uuid)
12451266
if success(p)
12461267
# append checksum to the end of the .ji file:

0 commit comments

Comments
 (0)