summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--script/SDBMHash.lua60
-rw-r--r--script/config/config.lua26
-rw-r--r--script/provider/build-meta.lua12
-rw-r--r--script/provider/provider.lua18
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