Skip to content

Commit 32f2b71

Browse files
committed
fix(cache): do a fast check to see if a cached modpath is still valid. find it again otherwise
1 parent 1fe43f3 commit 32f2b71

File tree

2 files changed

+62
-23
lines changed

2 files changed

+62
-23
lines changed

lua/lazy/core/cache.lua

+61-10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ local uv = vim.loop
44

55
local M = {}
66
M.dirty = false
7+
M.VERSION = "1"
78

89
---@class LazyCacheConfig
910
M.config = {
@@ -28,15 +29,36 @@ M.cache = {}
2829
M.loader_idx = 2 -- 2 so preload still works
2930
M.enabled = true
3031
M.ttl = 3600 * 24 * 5 -- keep unused modules for up to 5 days
32+
---@type string[]
33+
M.rtp = nil
3134

32-
-- Check if we need to load this plugin
33-
---@param modname string
34-
---@param modpath string
35-
function M.check_load(modname, modpath)
35+
-- checks wether the cached modpath is still valid
36+
function M.check_path(modname, modpath)
37+
-- check rtp exlcuding plugins. This is a very small list, so should be fast
38+
for _, path in ipairs(M.get_rtp()) do
39+
if modpath:find(path, 1, true) == 1 then
40+
return true
41+
end
42+
end
43+
44+
-- the correct lazy path should be part of rtp.
45+
-- so if we get here, this is folke using the local dev instance ;)
3646
if modname:sub(1, 4) == "lazy" then
37-
return
47+
return false
3848
end
39-
require("lazy.core.loader").check_load(modname, modpath)
49+
50+
-- check plugins. Again fast, since we check the plugin name from the path.
51+
-- only needed when the plugin mod has been loaded
52+
if package.loaded["lazy.core.plugin"] then
53+
local plugin = require("lazy.core.plugin").find(modpath)
54+
if plugin and modpath:find(plugin.dir, 1, true) == 1 then
55+
if not plugin._.loaded then
56+
require("lazy.core.loader").load(plugin, { require = modname })
57+
end
58+
return true
59+
end
60+
end
61+
return false
4062
end
4163

4264
function M.disable()
@@ -56,8 +78,7 @@ function M.loader(modname)
5678
local entry = M.cache[modname]
5779

5880
local chunk, err
59-
if entry then
60-
M.check_load(modname, entry.modpath)
81+
if entry and M.check_path(modname, entry.modpath) then
6182
entry.used = os.time()
6283
local hash = M.hash(entry.modpath)
6384
if not hash then
@@ -126,6 +147,28 @@ function M.find(modname)
126147
end
127148
end
128149

150+
function M.get_rtp()
151+
if not M.rtp then
152+
M.rtp = {}
153+
local skip = {}
154+
-- only skip plugins once Config has been setup
155+
if package.loaded["lazy.core.config"] then
156+
local Config = require("lazy.core.config")
157+
for _, plugin in ipairs(Config.plugins) do
158+
if plugin.name ~= "lazy.nvim" then
159+
skip[plugin.dir] = true
160+
end
161+
end
162+
end
163+
for _, path in ipairs(vim.api.nvim_list_runtime_paths()) do
164+
if not skip[path] then
165+
M.rtp[#M.rtp + 1] = path
166+
end
167+
end
168+
end
169+
return M.rtp
170+
end
171+
129172
---@param opts? LazyConfig
130173
function M.setup(opts)
131174
-- no fancy deep extend here. just set the options
@@ -139,6 +182,14 @@ function M.setup(opts)
139182
M.load_cache()
140183
table.insert(package.loaders, M.loader_idx, M.loader)
141184

185+
-- reset rtp when it changes
186+
vim.api.nvim_create_autocmd("OptionSet", {
187+
pattern = "runtimepath",
188+
callback = function()
189+
M.rtp = nil
190+
end,
191+
})
192+
142193
if #M.config.disable_events > 0 then
143194
vim.api.nvim_create_autocmd(M.config.disable_events, { once = true, callback = M.disable })
144195
end
@@ -159,7 +210,7 @@ end
159210

160211
function M.save_cache()
161212
local f = assert(uv.fs_open(M.config.path, "w", 438))
162-
uv.fs_write(f, vim.env.VIMRUNTIME)
213+
uv.fs_write(f, M.VERSION)
163214
uv.fs_write(f, "\0")
164215
for modname, entry in pairs(M.cache) do
165216
if entry.used > os.time() - M.ttl then
@@ -195,7 +246,7 @@ function M.load_cache()
195246
return
196247
end
197248

198-
if vim.env.VIMRUNTIME ~= data:sub(1, zero - 1) then
249+
if M.VERSION ~= data:sub(1, zero - 1) then
199250
return
200251
end
201252

lua/lazy/core/loader.lua

+1-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
local Util = require("lazy.core.util")
22
local Config = require("lazy.core.config")
33
local Handler = require("lazy.core.handler")
4+
local Cache = require("lazy.core.cache")
45

56
local M = {}
67

@@ -214,17 +215,4 @@ function M.autoload(modname)
214215
return modname .. " not found in lazy plugins"
215216
end
216217

217-
-- lazy.cache will call this when loading a cached file with modpath set.
218-
---@param modname string
219-
---@param modpath string
220-
function M.check_load(modname, modpath)
221-
-- no need to check anything before init
222-
if M.init_done then
223-
local plugin = require("lazy.core.plugin").find(modpath)
224-
if plugin and not plugin._.loaded then
225-
M.load(plugin, { require = modname })
226-
end
227-
end
228-
end
229-
230218
return M

0 commit comments

Comments
 (0)