mirror of
https://github.com/d0zingcat/rime_wanxiang.git
synced 2026-06-01 15:11:24 +00:00
chore:新的根节点
This commit is contained in:
68
lua/lib/bit.lua
Normal file
68
lua/lib/bit.lua
Normal file
@@ -0,0 +1,68 @@
|
||||
local bit_ok, bit_ = pcall(require, "bit") -- LuaJIT 内置 bit 库
|
||||
local bit32_ok, bit32_ = pcall(require, "bit32") -- Lua 5.2 内置 bit32 库
|
||||
|
||||
---@alias fn_band fun(a: integer, b: integer): integer
|
||||
---@alias fn_bxor fun(a: integer, b: integer): integer
|
||||
---@type nil | { band: fn_band, bxor: fn_bxor }
|
||||
local bit53_ = nil -- Lua 5.3 引入的原生位运算操作符
|
||||
|
||||
---@diagnostic disable-next-line: deprecated
|
||||
local load_func = load or loadstring
|
||||
if load_func then
|
||||
---将新语法放入字符串中,避免在旧版 Lua 中导致语法错误
|
||||
local bit53_func, bit53_err = load_func("return {" ..
|
||||
"band = function(a, b) return a & b end," ..
|
||||
"bxor = function(a, b) return a ~ b end," ..
|
||||
"}")
|
||||
if bit53_func and not bit53_err then
|
||||
bit53_ = bit53_func()
|
||||
end
|
||||
end
|
||||
|
||||
local bit = {}
|
||||
|
||||
---@return integer
|
||||
function bit.bxor(a, b)
|
||||
if bit_ok then
|
||||
return bit_.bxor(a, b)
|
||||
elseif bit32_ok then
|
||||
return bit32_.bxor(a, b)
|
||||
elseif bit53_ then
|
||||
return bit53_.bxor(a, b)
|
||||
end
|
||||
|
||||
local p, c = 1, 0
|
||||
while a > 0 and b > 0 do
|
||||
local ra, rb = a % 2, b % 2
|
||||
if ra ~= rb then c = c + p end
|
||||
a, b, p = (a - ra) / 2, (b - rb) / 2, p * 2
|
||||
end
|
||||
if a < b then a = b end
|
||||
while a > 0 do
|
||||
local ra = a % 2
|
||||
if ra > 0 then c = c + p end
|
||||
a, p = (a - ra) / 2, p * 2
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
---@return integer
|
||||
function bit.band(a, b)
|
||||
if bit_ok then
|
||||
return bit_.band(a, b)
|
||||
elseif bit32_ok then
|
||||
return bit32_.band(a, b)
|
||||
elseif bit53_ then
|
||||
return bit53_.band(a, b)
|
||||
end
|
||||
|
||||
local p, c = 1, 0
|
||||
while a > 0 and b > 0 do
|
||||
local ra, rb = a % 2, b % 2
|
||||
if ra + rb > 1 then c = c + p end
|
||||
a, b, p = (a - ra) / 2, (b - rb) / 2, p * 2
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
return bit
|
||||
116
lua/lib/userdb.lua
Normal file
116
lua/lib/userdb.lua
Normal file
@@ -0,0 +1,116 @@
|
||||
local META_KEY_PREFIX = "\001" .. "/"
|
||||
|
||||
-- UserDb 缓存,使用弱引用表,不阻止垃圾回收并能自动清理
|
||||
local db_pool = setmetatable({}, { __mode = "v" })
|
||||
|
||||
---@class WrappedUserDb: UserDb
|
||||
---@field meta_query fun(self: self, prefix: string): DbAccessor
|
||||
---@field meta_fetch fun(self: self, key: string): string|nil
|
||||
---@field meta_update fun(self: self, key: string, value: string): boolean
|
||||
---@field meta_erase fun(self: self, key: string): boolean
|
||||
---@field query_with fun(self: self, prefix: string, handler: fun(key: string, value: string))
|
||||
---@field empty fun(self: self, include_metafield?: boolean) -- 清空数据库
|
||||
|
||||
-- 用于存放包装器对象的自定义方法
|
||||
local extends = {}
|
||||
|
||||
--- @param key string
|
||||
--- @return string|nil
|
||||
function extends:meta_fetch(key)
|
||||
return self._db:fetch(META_KEY_PREFIX .. key)
|
||||
end
|
||||
|
||||
--- @param key string
|
||||
--- @param value string
|
||||
--- @return boolean
|
||||
function extends:meta_update(key, value)
|
||||
return self._db:update(META_KEY_PREFIX .. key, value)
|
||||
end
|
||||
|
||||
--- @param key string
|
||||
--- @return boolean
|
||||
function extends:meta_erase(key)
|
||||
return self._db:erase(META_KEY_PREFIX .. key)
|
||||
end
|
||||
|
||||
--- @param prefix string
|
||||
--- @return DbAccessor
|
||||
function extends:meta_query(prefix)
|
||||
return self._db:query(META_KEY_PREFIX .. prefix)
|
||||
end
|
||||
|
||||
function extends:query_with(prefix, handler)
|
||||
local da = self._db:query(prefix)
|
||||
if da then
|
||||
for key, value in da:iter() do
|
||||
handler(key, value)
|
||||
end
|
||||
end
|
||||
da = nil
|
||||
collectgarbage()
|
||||
end
|
||||
|
||||
--- @param include_metafield boolean 是否也清理元数据。
|
||||
function extends:empty(include_metafield)
|
||||
self:query_with("", function(key, _)
|
||||
local is_metafield = key:find(META_KEY_PREFIX, 1, true) == 1
|
||||
if include_metafield or not is_metafield then
|
||||
self._db:erase(key)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local mt = {
|
||||
__index = function(wrapper, key)
|
||||
-- 优先使用自定义方法
|
||||
if extends[key] then
|
||||
return extends[key]
|
||||
end
|
||||
|
||||
-- 不是自定义方法,委托给真实的 UserDb 对象
|
||||
local real_db = wrapper._db
|
||||
local value = real_db[key]
|
||||
|
||||
if type(value) == "function" then
|
||||
return function(_, ...)
|
||||
return value(real_db, ...)
|
||||
end
|
||||
end
|
||||
|
||||
return value
|
||||
end,
|
||||
}
|
||||
|
||||
local userdb = {}
|
||||
|
||||
--- @param db_name string
|
||||
--- @param db_class "userdb" | "plain_userdb" | nil
|
||||
--- @return WrappedUserDb
|
||||
function userdb.UserDb(db_name, db_class)
|
||||
db_class = db_class or "userdb"
|
||||
local key = db_name .. "." .. db_class
|
||||
|
||||
---@type UserDb
|
||||
local db = db_pool[key]
|
||||
if not db then
|
||||
db = UserDb(db_name, db_class)
|
||||
db_pool[key] = db
|
||||
end
|
||||
|
||||
local wrapper = {
|
||||
_db = db,
|
||||
_pool_key = key,
|
||||
}
|
||||
|
||||
return setmetatable(wrapper, mt)
|
||||
end
|
||||
|
||||
function userdb.LevelDb(db_name)
|
||||
return userdb.UserDb(db_name, "userdb")
|
||||
end
|
||||
|
||||
function userdb.TableDb(db_name)
|
||||
return userdb.UserDb(db_name, "plain_userdb")
|
||||
end
|
||||
|
||||
return userdb
|
||||
Reference in New Issue
Block a user