mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-05 11:18:26 +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:
|
-- Frecency based on exponential decay. Roughly based on:
|
||||||
-- https://wiki.mozilla.org/User:Jesse/NewFrecency?title=User:Jesse/NewFrecency
|
-- https://wiki.mozilla.org/User:Jesse/NewFrecency?title=User:Jesse/NewFrecency
|
||||||
---@class snacks.picker.Frecency
|
---@class snacks.picker.Frecency
|
||||||
---@field store table<string, number>
|
|
||||||
---@field now number
|
---@field now number
|
||||||
|
---@field cache table<string, number>
|
||||||
local M = {}
|
local M = {}
|
||||||
M.__index = 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 set fun(self:snacks.picker.frecency.Store, key:string, value:number)
|
||||||
---@field get fun(self:snacks.picker.frecency.Store, key:string):number
|
---@field get fun(self:snacks.picker.frecency.Store, key:string):number
|
||||||
---@field close fun(self:snacks.picker.frecency.Store)
|
---@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
|
-- Global store of frecency deadlinesl
|
||||||
---@type snacks.picker.frecency.Store?
|
---@type snacks.picker.frecency.Store?
|
||||||
|
@ -28,7 +29,7 @@ function M.setup()
|
||||||
if
|
if
|
||||||
not pcall(function()
|
not pcall(function()
|
||||||
local db = require("snacks.picker.util.db").new(store_file .. ".sqlite3", "number")
|
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
|
-- Cleanup old entries
|
||||||
local cutoff = db:prepare("SELECT value FROM data ORDER BY value DESC LIMIT 1 OFFSET ?;")
|
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
|
if cutoff:exec({ MAX_STORE_SIZE - 1 }) == 100 then -- 100 == SQLITE_ROW
|
||||||
|
@ -36,7 +37,7 @@ function M.setup()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
then
|
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
|
end
|
||||||
|
|
||||||
local group = vim.api.nvim_create_augroup("snacks_picker_frecency", {})
|
local group = vim.api.nvim_create_augroup("snacks_picker_frecency", {})
|
||||||
|
@ -67,6 +68,7 @@ function M.new()
|
||||||
if not M.store then
|
if not M.store then
|
||||||
M.setup()
|
M.setup()
|
||||||
end
|
end
|
||||||
|
self.cache = M.store:get_all()
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -94,7 +96,7 @@ function M:get(item, opts)
|
||||||
if not path then
|
if not path then
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
local deadline = self.store:get(path)
|
local deadline = self.cache[path]
|
||||||
if not deadline then
|
if not deadline then
|
||||||
return opts.seed ~= false and self:seed(item) or 0
|
return opts.seed ~= false and self:seed(item) or 0
|
||||||
end
|
end
|
||||||
|
|
|
@ -86,6 +86,7 @@ function Query:exec(binds)
|
||||||
return self:step()
|
return self:step()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@return number
|
||||||
function Query:step()
|
function Query:step()
|
||||||
return sqlite.sqlite3_step(self.stmt)
|
return sqlite.sqlite3_step(self.stmt)
|
||||||
end
|
end
|
||||||
|
@ -204,4 +205,18 @@ function M:count()
|
||||||
end
|
end
|
||||||
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
|
return M
|
||||||
|
|
|
@ -42,6 +42,10 @@ function M:get(key)
|
||||||
return self.data[key]
|
return self.data[key]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M:get_all()
|
||||||
|
return self.data
|
||||||
|
end
|
||||||
|
|
||||||
function M:close()
|
function M:close()
|
||||||
vim.fn.mkdir(vim.fn.fnamemodify(self.path, ":h"), "p")
|
vim.fn.mkdir(vim.fn.fnamemodify(self.path, ":h"), "p")
|
||||||
local stat = uv.fs_stat(self.path)
|
local stat = uv.fs_stat(self.path)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue