mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-04 18:58:12 +00:00
perf(picker.frecency): cache all deadlines on load
This commit is contained in:
parent
c2916cb526
commit
5b3625bcea
3 changed files with 25 additions and 4 deletions
|
@ -1,8 +1,8 @@
|
|||
-- Frecency based on exponential decay. Roughly based on:
|
||||
-- https://wiki.mozilla.org/User:Jesse/NewFrecency?title=User:Jesse/NewFrecency
|
||||
---@class snacks.picker.Frecency
|
||||
---@field store table<string, number>
|
||||
---@field now number
|
||||
---@field cache table<string, number>
|
||||
local M = {}
|
||||
M.__index = M
|
||||
|
||||
|
@ -19,6 +19,7 @@ local MAX_STORE_SIZE = 10000
|
|||
---@field set fun(self:snacks.picker.frecency.Store, key:string, value:number)
|
||||
---@field get fun(self:snacks.picker.frecency.Store, key:string):number
|
||||
---@field close fun(self:snacks.picker.frecency.Store)
|
||||
---@field get_all fun(self:snacks.picker.frecency.Store):table<string, number>
|
||||
|
||||
-- Global store of frecency deadlinesl
|
||||
---@type snacks.picker.frecency.Store?
|
||||
|
@ -28,7 +29,7 @@ function M.setup()
|
|||
if
|
||||
not pcall(function()
|
||||
local db = require("snacks.picker.util.db").new(store_file .. ".sqlite3", "number")
|
||||
M.store = db
|
||||
M.store = db --[[@as snacks.picker.frecency.Store]]
|
||||
-- Cleanup old entries
|
||||
local cutoff = db:prepare("SELECT value FROM data ORDER BY value DESC LIMIT 1 OFFSET ?;")
|
||||
if cutoff:exec({ MAX_STORE_SIZE - 1 }) == 100 then -- 100 == SQLITE_ROW
|
||||
|
@ -36,7 +37,7 @@ function M.setup()
|
|||
end
|
||||
end)
|
||||
then
|
||||
M.store = require("snacks.picker.util.kv").new(store_file .. ".dat", { max_size = MAX_STORE_SIZE })
|
||||
M.store = require("snacks.picker.util.kv").new(store_file .. ".dat", { max_size = MAX_STORE_SIZE }) --[[@as snacks.picker.frecency.Store]]
|
||||
end
|
||||
|
||||
local group = vim.api.nvim_create_augroup("snacks_picker_frecency", {})
|
||||
|
@ -67,6 +68,7 @@ function M.new()
|
|||
if not M.store then
|
||||
M.setup()
|
||||
end
|
||||
self.cache = M.store:get_all()
|
||||
return self
|
||||
end
|
||||
|
||||
|
@ -94,7 +96,7 @@ function M:get(item, opts)
|
|||
if not path then
|
||||
return 0
|
||||
end
|
||||
local deadline = self.store:get(path)
|
||||
local deadline = self.cache[path]
|
||||
if not deadline then
|
||||
return opts.seed ~= false and self:seed(item) or 0
|
||||
end
|
||||
|
|
|
@ -86,6 +86,7 @@ function Query:exec(binds)
|
|||
return self:step()
|
||||
end
|
||||
|
||||
---@return number
|
||||
function Query:step()
|
||||
return sqlite.sqlite3_step(self.stmt)
|
||||
end
|
||||
|
@ -204,4 +205,18 @@ function M:count()
|
|||
end
|
||||
end
|
||||
|
||||
function M:get_all()
|
||||
local query = self:prepare("SELECT key, value FROM data;")
|
||||
local ret = {} ---@type table<string, any>
|
||||
local code = query:exec()
|
||||
while code == 100 do -- 100 == SQLITE_ROW
|
||||
local k = query:col("string", 0) -- key is always a string
|
||||
local v = query:col(self.type, 1) -- value type is whatever you set
|
||||
ret[k] = v
|
||||
code = query:step()
|
||||
end
|
||||
query:close()
|
||||
return ret
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
@ -42,6 +42,10 @@ function M:get(key)
|
|||
return self.data[key]
|
||||
end
|
||||
|
||||
function M:get_all()
|
||||
return self.data
|
||||
end
|
||||
|
||||
function M:close()
|
||||
vim.fn.mkdir(vim.fn.fnamemodify(self.path, ":h"), "p")
|
||||
local stat = uv.fs_stat(self.path)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue