mirror of
https://github.com/neovim/neovim.git
synced 2025-09-05 19:08:15 +00:00
refactor(hashy): use case labels instead of TOLOWER_ASC() (#32795)
Follow-up to #32768 This is slightly faster according to the benchmark. This also makes it a build error if hashy is used incorrectly (generating a case-insensitive hash function from mixed-case strings), as duplicate case labels aren't allowed.
This commit is contained in:
@@ -54,7 +54,7 @@ function M.build_pos_hash(strings)
|
||||
return len_pos_buckets, maxlen, worst_buck_size
|
||||
end
|
||||
|
||||
function M.switcher(put, tab, maxlen, worst_buck_size, lower)
|
||||
function M.switcher(put, tab, maxlen, worst_buck_size, icase)
|
||||
local neworder = {} --- @type string[]
|
||||
put ' switch (len) {\n'
|
||||
local bucky = worst_buck_size > 1
|
||||
@@ -66,13 +66,17 @@ function M.switcher(put, tab, maxlen, worst_buck_size, lower)
|
||||
local keys = vim.tbl_keys(posbuck)
|
||||
if #keys > 1 then
|
||||
table.sort(keys)
|
||||
put(('switch (%s(str[%s])) {\n'):format(lower and 'TOLOWER_ASC' or '', pos - 1))
|
||||
put('switch (str[' .. (pos - 1) .. ']) {\n')
|
||||
for _, c in ipairs(keys) do
|
||||
local buck = posbuck[c]
|
||||
local startidx = #neworder
|
||||
vim.list_extend(neworder, buck)
|
||||
local endidx = #neworder
|
||||
put(" case '" .. c .. "': ")
|
||||
if icase and c:upper() ~= c:lower() then
|
||||
put((" case '%s': case '%s': "):format(c:upper(), c:lower()))
|
||||
else
|
||||
put((" case '%s': "):format(c))
|
||||
end
|
||||
if len == 1 then
|
||||
put('return ' .. startidx .. ';\n')
|
||||
else
|
||||
@@ -102,7 +106,9 @@ function M.switcher(put, tab, maxlen, worst_buck_size, lower)
|
||||
return neworder
|
||||
end
|
||||
|
||||
function M.hashy_hash(name, strings, access, lower)
|
||||
--- @param icase boolean generate a case-insensitive hash function.
|
||||
--- `strings` must not have mixed case when using this.
|
||||
function M.hashy_hash(name, strings, access, icase)
|
||||
local stats = {}
|
||||
local put = function(str)
|
||||
table.insert(stats, str)
|
||||
@@ -116,7 +122,7 @@ function M.hashy_hash(name, strings, access, lower)
|
||||
else
|
||||
put(' int low = -1;\n')
|
||||
end
|
||||
local neworder = M.switcher(put, len_pos_buckets, maxlen, worst_buck_size, lower)
|
||||
local neworder = M.switcher(put, len_pos_buckets, maxlen, worst_buck_size, icase)
|
||||
if maxlen == 1 then
|
||||
put([[
|
||||
return -1;
|
||||
@@ -129,14 +135,14 @@ function M.hashy_hash(name, strings, access, lower)
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
]]):format(lower and 'vim_strnicmp_asc' or 'memcmp', access('i')))
|
||||
]]):format(icase and 'vim_strnicmp_asc' or 'memcmp', access('i')))
|
||||
else
|
||||
put(([[
|
||||
if (low < 0 || %s(str, %s, len)) {
|
||||
return -1;
|
||||
}
|
||||
return low;
|
||||
]]):format(lower and 'vim_strnicmp_asc' or 'memcmp', access('low')))
|
||||
]]):format(icase and 'vim_strnicmp_asc' or 'memcmp', access('low')))
|
||||
end
|
||||
put '}\n\n'
|
||||
return neworder, table.concat(stats)
|
||||
|
Reference in New Issue
Block a user