diff options
-rw-r--r-- | script/SDBMHash.lua | 60 | ||||
-rw-r--r-- | script/config/config.lua | 26 | ||||
-rw-r--r-- | script/provider/build-meta.lua | 12 | ||||
-rw-r--r-- | script/provider/provider.lua | 18 |
4 files changed, 86 insertions, 30 deletions
diff --git a/script/SDBMHash.lua b/script/SDBMHash.lua new file mode 100644 index 00000000..48728aec --- /dev/null +++ b/script/SDBMHash.lua @@ -0,0 +1,60 @@ +local byte = string.byte +local max = 0x7fffffff + +---@class SDBMHash +local mt = {} +mt.__index = mt + +mt.cache = nil + +---@param str string +---@return integer +function mt:rawHash(str) + local id = 0 + for i = 1, #str do + local b = byte(str, i, i) + id = id * 65599 + b + end + return id & max +end + +---@param str string +---@return integer +function mt:hash(str) + local id = self:rawHash(str) + local other = self.cache[id] + if other == nil or str == other then + self.cache[id] = str + self.cache[str] = id + return id + else + log.warn(('哈希碰撞:[%s] -> [%s]: [%d]'):format(str, other, id)) + for i = 1, max do + local newId = (id + i) % max + if not self.cache[newId] then + self.cache[newId] = str + self.cache[str] = newId + return newId + end + end + error(('哈希碰撞解决失败:[%s] -> [%s]: [%d]'):format(str, other, id)) + end +end + +function mt:setCache(t) + self.cache = t +end + +function mt:getCache() + return self.cache +end + +mt.__call = mt.hash + +---@return SDBMHash +return function () + local self = setmetatable({ + cache = {} + }, mt) + return self +end diff --git a/script/config/config.lua b/script/config/config.lua index fb72e7c9..70e83fc8 100644 --- a/script/config/config.lua +++ b/script/config/config.lua @@ -74,6 +74,8 @@ end ---@param key string ---@param value any function m.set(uri, key, value) + local unit = template[key] + assert(unit, 'unknown key: ' .. key) local scp = getScope(uri) local oldValue = m.get(uri, key) m.setByScope(scp, key, value) @@ -87,13 +89,9 @@ end function m.add(uri, key, value) local unit = template[key] - if not unit then - return false - end + assert(unit, 'unknown key: ' .. key) local list = m.getRaw(uri, key) - if type(list) ~= 'table' then - return false - end + assert(type(list) == 'table', 'not a list: ' .. key) local copyed = {} for i, v in ipairs(list) do if util.equal(v, value) then @@ -114,13 +112,9 @@ end function m.remove(uri, key, value) local unit = template[key] - if not unit then - return false - end + assert(unit, 'unknown key: ' .. key) local list = m.getRaw(uri, key) - if type(list) ~= 'table' then - return false - end + assert(type(list) == 'table', 'not a list: ' .. key) local copyed = {} for i, v in ipairs(list) do if not util.equal(v, value) then @@ -139,13 +133,9 @@ end function m.prop(uri, key, prop, value) local unit = template[key] - if not unit then - return false - end + assert(unit, 'unknown key: ' .. key) local map = m.getRaw(uri, key) - if type(map) ~= 'table' then - return false - end + assert(type(map) == 'table', 'not a map: ' .. key) if util.equal(map[prop], value) then return false end diff --git a/script/provider/build-meta.lua b/script/provider/build-meta.lua index 21390411..090b7b04 100644 --- a/script/provider/build-meta.lua +++ b/script/provider/build-meta.lua @@ -124,13 +124,9 @@ local function buildRootText(api) end ---@async ----@param name string +---@param path string ---@param api meta ----@return string -function m.build(name, api) - local encoding = config.get(nil, 'Lua.runtime.fileEncoding') - local fileDir = fs.path(METAPATH) / (name .. ' ' .. encoding) - fs.create_directories(fileDir) +function m.build(path, api) local files = util.multiTable(2, function () return { '---@meta' } @@ -149,10 +145,8 @@ function m.build(name, api) end for space, texts in pairs(files) do - util.saveFile((fileDir / (space .. '.lua')):string(), table.concat(texts, '\n\n')) + util.saveFile(path .. '/' .. space .. '.lua', table.concat(texts, '\n\n')) end - - return fileDir:string() end return m diff --git a/script/provider/provider.lua b/script/provider/provider.lua index a5255f44..eb1362eb 100644 --- a/script/provider/provider.lua +++ b/script/provider/provider.lua @@ -21,6 +21,7 @@ local furi = require 'file-uri' local inspect = require 'inspect' local markdown = require 'provider.markdown' local guide = require 'parser.guide' +local fs = require 'bee.filesystem' ---@async local function updateConfig(uri) @@ -1342,14 +1343,25 @@ m.register '$/api/report' { ---@async function (params) local buildMeta = require 'provider.build-meta' + local SDBMHash = require 'SDBMHash' await.close 'api/report' await.setID 'api/report' - local dir = buildMeta.build('default', params) + local name = params.name or 'default' + local uri = workspace.getFirstScope().uri + local hash = uri and ('%08x'):format(SDBMHash():hash(uri)) + local encoding = config.get(nil, 'Lua.runtime.fileEncoding') + local nameBuf = {} + nameBuf[#nameBuf+1] = name + nameBuf[#nameBuf+1] = hash + nameBuf[#nameBuf+1] = encoding + local fileDir = METAPATH .. '/' .. table.concat(nameBuf, ' ') + fs.create_directories(fs.path(fileDir)) + buildMeta.build(fileDir, params) client.setConfig { { - key = 'Lua.runtime.library', + key = 'Lua.workspace.library', action = 'add', - value = dir, + value = fileDir, } } end |