aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2025-03-09 08:58:18 +0800
committerGitHub <noreply@github.com>2025-03-09 00:58:18 +0000
commit5ee62906a336b36bd868b5dda70037dc02525b15 (patch)
treee52cf6664eefcfbf91b04669aeeeda5dd06aabd1
parent8ea18119e7bbbf956680266b6e1a69bc5fa4b40d (diff)
downloadrneovim-5ee62906a336b36bd868b5dda70037dc02525b15.tar.gz
rneovim-5ee62906a336b36bd868b5dda70037dc02525b15.tar.bz2
rneovim-5ee62906a336b36bd868b5dda70037dc02525b15.zip
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.
-rw-r--r--src/gen/hashy.lua20
1 files changed, 13 insertions, 7 deletions
diff --git a/src/gen/hashy.lua b/src/gen/hashy.lua
index 7fdb00699f..52cc1e64e3 100644
--- a/src/gen/hashy.lua
+++ b/src/gen/hashy.lua
@@ -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)