Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: significantly speed up feature parsing #92

Merged
merged 1 commit into from
Nov 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions lua/crates/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -156,17 +156,17 @@ function M.parse_crate(json_str)

for n, m in pairs(v.features) do
table.sort(m)
table.insert(version.features, {
version.features:insert({
name = n,
members = m,
})
end


for _, f in ipairs(version.features) do
for _, f in ipairs(version.features.list) do
for _, m in ipairs(f.members) do
if not version.features:get_feat(m) then
table.insert(version.features, {
version.features:insert({
name = m,
members = {},
})
Expand All @@ -178,15 +178,11 @@ function M.parse_crate(json_str)
version.features:sort()


if not version.features[1] or not (version.features[1].name == "default") then
for i = #version.features, 1, -1 do
version.features[i + 1] = version.features[i]
end

version.features[1] = {
if not version.features.list[1] or not (version.features.list[1].name == "default") then
version.features:insert({
name = "default",
members = {},
}
})
end

table.insert(crate.versions, version)
Expand Down
2 changes: 1 addition & 1 deletion lua/crates/core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ M.reload_deps = async.wrap(function(crate_name, versions, version)
for _, d in ipairs(deps) do

if d.opt and not version.features:get_feat(d.name) then
table.insert(version.features, {
version.features:insert({
name = d.name,
members = {},
})
Expand Down
2 changes: 1 addition & 1 deletion lua/crates/diagnostic.lua
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ function M.process_crate_deps(crate, version, deps)
local diagnostics = {}

local valid_feats = {}
for _, f in ipairs(version.features) do
for _, f in ipairs(version.features.list) do
table.insert(valid_feats, f.name)
end
for _, d in ipairs(deps) do
Expand Down
10 changes: 5 additions & 5 deletions lua/crates/popup/features.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ local function toggle_feature(ctx, line)
selected_feature = features:get_feat(m)
end
else
selected_feature = features[index]
selected_feature = features.list[index]
end
if not selected_feature then return end

Expand Down Expand Up @@ -128,7 +128,7 @@ local function toggle_feature(ctx, line)
table.insert(features_text, hi_text)
end
else
for _, f in ipairs(features) do
for _, f in ipairs(features.list) do
local hi_text = feature_text(features_info, f)
table.insert(features_text, hi_text)
end
Expand All @@ -150,7 +150,7 @@ local function goto_feature(ctx, line)
selected_feature = version.features:get_feat(m)
end
else
selected_feature = version.features[index]
selected_feature = version.features.list[index]
end
if not selected_feature then return end

Expand Down Expand Up @@ -292,7 +292,7 @@ function M.open_features(ctx, crate, version, opts)
local features_text = {}

local features_info = util.features_info(crate, features)
for _, f in ipairs(features) do
for _, f in ipairs(features.list) do
local hl_text = feature_text(features_info, f)
table.insert(features_text, hl_text)
local w = 0
Expand All @@ -303,7 +303,7 @@ function M.open_features(ctx, crate, version, opts)
end

local width = popup.win_width(title, feat_width)
local height = popup.win_height(features)
local height = popup.win_height(features.list)

if opts.update then
popup.update_win(width, height, title, features_text, opts)
Expand Down
2 changes: 1 addition & 1 deletion lua/crates/src/common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ local function complete_features(crate, cf, versions)
end

local items = {}
for _, f in ipairs(newest.features) do
for _, f in ipairs(newest.features.list) do
local crate_feat = crate:get_feat(f.name)
if not crate_feat then
local r = {
Expand Down
24 changes: 14 additions & 10 deletions lua/crates/types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ local M = {CrateInfo = {}, Diagnostic = {}, Crate = {}, Version = {}, Features =






local Diagnostic = M.Diagnostic
Expand All @@ -151,22 +152,20 @@ function Diagnostic:contains(line, col)
end


function Features.new(obj)
return setmetatable(obj, { __index = Features })
function Features.new(list)
local map = {}
for _, f in ipairs(list) do
map[f.name] = f
end
return setmetatable({ list = list, map = map }, { __index = Features })
end

function Features:get_feat(name)
for i, f in ipairs(self) do
if f.name == name then
return f, i
end
end

return nil, nil
return self.map[name]
end

function Features:sort()
table.sort(self, function(a, b)
table.sort(self.list, function(a, b)
if a.name == "default" then
return true
elseif b.name == "default" then
Expand All @@ -177,6 +176,11 @@ function Features:sort()
end)
end

function Features:insert(feat)
table.insert(self.list, feat)
self.map[feat.name] = feat
end


function SemVer.new(obj)
return setmetatable(obj, { __index = SemVer })
Expand Down
2 changes: 1 addition & 1 deletion lua/crates/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ function M.features_info(crate, features)
end
end

for _, f in ipairs(features) do
for _, f in ipairs(features.list) do
local enabled = M.is_feat_enabled(crate, f)
local i = info[f.name]
if i then
Expand Down
18 changes: 7 additions & 11 deletions teal/crates/api.tl
Original file line number Diff line number Diff line change
Expand Up @@ -148,25 +148,25 @@ function M.parse_crate(json_str: string): Crate|nil
if v.num then
local version: Version = {
num = v.num as string,
features = Features.new {},
features = Features.new({}),
yanked = v.yanked as boolean,
parsed = semver.parse_version(v.num as string),
created = DateTime.parse_rfc_3339(v.created_at as string)
}

for n,m in pairs(v.features as {string:{string}}) do
table.sort(m)
table.insert(version.features, {
version.features:insert({
name = n,
members = m,
})
end

-- add optional dependency members as features
for _,f in ipairs(version.features) do
for _,f in ipairs(version.features.list) do
for _,m in ipairs(f.members) do
if not version.features:get_feat(m) then
table.insert(version.features, {
version.features:insert({
name = m,
members = {},
})
Expand All @@ -178,15 +178,11 @@ function M.parse_crate(json_str: string): Crate|nil
version.features:sort()

-- add missing default feature
if not version.features[1] or not (version.features[1].name == "default") then
for i=#version.features, 1, -1 do
version.features[i + 1] = version.features[i]
end

version.features[1] = {
if not version.features.list[1] or not (version.features.list[1].name == "default") then
version.features:insert({
name = "default",
members = {},
}
})
end

table.insert(crate.versions, version)
Expand Down
2 changes: 1 addition & 1 deletion teal/crates/core.tl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ M.reload_deps = async.wrap(function(crate_name: string, versions: {Version}, ver
for _,d in ipairs(deps) do
-- optional dependencies are automatically promoted to features
if d.opt and not version.features:get_feat(d.name) then
table.insert(version.features, {
version.features:insert({
name = d.name,
members = {},
})
Expand Down
2 changes: 1 addition & 1 deletion teal/crates/diagnostic.tl
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ function M.process_crate_deps(crate: toml.Crate, version: Version, deps: {Depend
local diagnostics = {}

local valid_feats = {}
for _,f in ipairs(version.features) do
for _,f in ipairs(version.features.list) do
table.insert(valid_feats, f.name)
end
for _,d in ipairs(deps) do
Expand Down
10 changes: 5 additions & 5 deletions teal/crates/popup/features.tl
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ local function toggle_feature(ctx: FeatureContext, line: integer)
selected_feature = features:get_feat(m)
end
else
selected_feature = features[index]
selected_feature = features.list[index]
end
if not selected_feature then return end

Expand Down Expand Up @@ -128,7 +128,7 @@ local function toggle_feature(ctx: FeatureContext, line: integer)
table.insert(features_text, hi_text)
end
else
for _,f in ipairs(features) do
for _,f in ipairs(features.list) do
local hi_text = feature_text(features_info, f)
table.insert(features_text, hi_text)
end
Expand All @@ -150,7 +150,7 @@ local function goto_feature(ctx: FeatureContext, line: integer)
selected_feature = version.features:get_feat(m)
end
else
selected_feature = version.features[index]
selected_feature = version.features.list[index]
end
if not selected_feature then return end

Expand Down Expand Up @@ -292,7 +292,7 @@ function M.open_features(ctx: FeatureContext, crate: toml.Crate, version: Versio
local features_text: {{HighlightText}} = {}

local features_info = util.features_info(crate, features)
for _,f in ipairs(features) do
for _,f in ipairs(features.list) do
local hl_text = feature_text(features_info, f)
table.insert(features_text, hl_text)
local w = 0
Expand All @@ -303,7 +303,7 @@ function M.open_features(ctx: FeatureContext, crate: toml.Crate, version: Versio
end

local width = popup.win_width(title, feat_width)
local height = popup.win_height(features)
local height = popup.win_height(features.list)

if opts.update then
popup.update_win(width, height, title, features_text, opts)
Expand Down
2 changes: 1 addition & 1 deletion teal/crates/src/common.tl
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ local function complete_features(crate: toml.Crate, cf: toml.Feature, versions:
end

local items = {}
for _,f in ipairs(newest.features) do
for _,f in ipairs(newest.features.list) do
local crate_feat = crate:get_feat(f.name)
if not crate_feat then
local r: CompletionItem = {
Expand Down
28 changes: 16 additions & 12 deletions teal/crates/types.tl
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ local record M
end

record Features
{Feature}
list: {Feature}
map: {string:Feature}
end

record Feature
Expand Down Expand Up @@ -151,22 +152,20 @@ function Diagnostic:contains(line: integer, col: integer): boolean
end


function Features.new(obj: Features): Features
return setmetatable(obj, { __index = Features })
end

function Features:get_feat(name: string): Feature|nil, integer|nil
for i,f in ipairs(self) do
if f.name == name then
return f, i
end
function Features.new(list: {Feature}): Features
local map = {}
for _,f in ipairs(list) do
map[f.name] = f
end
return setmetatable({ list = list, map = map }, { __index = Features })
end

return nil, nil
function Features:get_feat(name: string): Feature|nil
return self.map[name]
end

function Features:sort()
table.sort(self, function (a: Feature, b: Feature): boolean
table.sort(self.list, function (a: Feature, b: Feature): boolean
if a.name == "default" then
return true
elseif b.name == "default" then
Expand All @@ -177,6 +176,11 @@ function Features:sort()
end)
end

function Features:insert(feat: Feature)
table.insert(self.list, feat)
self.map[feat.name] = feat
end


function SemVer.new(obj: SemVer): SemVer
return setmetatable(obj, { __index = SemVer })
Expand Down
2 changes: 1 addition & 1 deletion teal/crates/util.tl
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ function M.features_info(crate: toml.Crate, features: Features): {string:Feature
end
end

for _,f in ipairs(features) do
for _,f in ipairs(features.list) do
local enabled = M.is_feat_enabled(crate, f)
local i = info[f.name]
if i then
Expand Down
Loading