Skip to content

Commit

Permalink
perf: significantly speed up feature parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
saecki committed Nov 18, 2023
1 parent f47c77d commit 2bccfd6
Show file tree
Hide file tree
Showing 14 changed files with 61 additions and 61 deletions.
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

0 comments on commit 2bccfd6

Please sign in to comment.