当调用db.del时似乎是伪删除 each函数会报错
Runtime error: db.lua:909: not enough memory for buffer allocation
stack traceback:
[C]: in method 'read'
db.lua:909: in for iterator 'for iterator'
以下是我尝试修改的del函数 但修改失败了 但实现了对于db文件和map文件部分清理 而且修改后each函数无法使用 可是本人太菜导致并未成功修复--- 删除成员
`---@param k any|LUADB_ID|LUADB_ADDR 成员key
---@return LuaDB
function db:del(k)
-- 申明变量
local F = self.F
local fw, fm = self.fw, self.fm
-- 得到成员属性
local po, addr, size, _, ck, level = self:check_key(k)
-- key转换类型,用于判断是否碰撞
k = tostring(k)
-- 读取原本存储的数据类型和长度
fw:seek('set', addr + 8 + size)
local tp = unpack(F.B, fw:read(1))
local n = self:packsize(tp)
-- 计算数据总长度
local total_len = 8 + size + 1 + n
-- 从文件中删除数据
-- 先备份数据后面的部分
local backup = fw:read(fw:seek('end') - (addr + total_len))
-- 如果备份为空,确保它是一个空字符串
backup = backup or ''
-- 清空要删除的数据
fw:seek('set', addr)
fw:write(string.rep('\0', total_len))
-- 将备份的数据写回到文件中
fw:seek('end')
fw:write(backup)
-- 更新索引,移除该键值对的记录
local block_size = self.block_size
local addr_size = self.addr_size
local hash_code = (hash(k) % block_size) + 1 -- 获取hash值
k = tostring(k) -- key转字符串
if self.can_each then
block_size = block_size * 2
hash_code = hash_code * 2
end
-- 计算实际占用空间
block_size = block_size * addr_size
-- 计算指针实际位置
hash_code = hash_code * addr_size
while true do
local po1 = (level * block_size) + hash_code
fm:seek('set', po1)
local addr1 = fm:read(addr_size)
if addr1 then
addr1 = unpack(F.A, addr1)
else
addr1 = 0
end
local po2 = ((level - 1) * block_size) + hash_code
fm:seek('set', po2)
fm:write((pack(F.A, addr1)))
if addr1 == 0 then
break
end
level = level + 1 -- 下降深度
end
-- 如果删除的是文件末尾的数据,重新写入文件
if addr + total_len == fw:seek('end') then
-- 创建临时文件
local temp_file = io.open(self.path .. '.tmp', 'wb')
local pos = 0
while pos < addr do
pos = pos + 1024
fw:seek('set', pos - 1024)
temp_file:write(fw:read(1024))
end
temp_file:close()
-- 替换原始文件
os.remove(self.path)
os.rename(self.path .. '.tmp', self.path)
end
-- 更新成员指针链表中的指针
self:update_pointers_after_delete(k, addr)
-- 清理成员指针链表
self:cleanup_pointers()
return self
end
--- 更新成员指针链表中的指针
---@param k string 成员key
---@param addr number 被删除成员的地址
function db:update_pointers_after_delete(k, addr)
-- 更新成员指针链表中的指针
local block_size = self.block_size
local addr_size = self.addr_size
local hash_code = (hash(k) % block_size) + 1 -- 获取hash值
if self.can_each then
block_size = block_size * 2
hash_code = hash_code * 2
end
-- 计算实际占用空间
block_size = block_size * addr_size
-- 计算指针实际位置
hash_code = hash_code * addr_size
local level = 0
while true do
local po = (level * block_size) + hash_code
local fm = self.fm
fm:seek('set', po)
local addr1 = fm:read(addr_size)
if addr1 then
addr1 = unpack(self.F.A, addr1)
else
addr1 = 0
end
if addr1 == addr then
-- 如果当前地址是要删除的地址
-- 获取下一个有效地址
local next_addr = self:get_next_addr(addr)
-- 更新指针
fm:seek('set', po)
fm:write((pack(self.F.A, next_addr)))
elseif addr1 == 0 then
break
end
level = level + 1 -- 下降深度
end
end
--- 清理成员指针链表
---@return LuaDB
function db:cleanup_pointers()
-- 遍历成员指针链表,清理无效的指针
local block_size = self.block_size
local addr_size = self.addr_size
local hash_code = (hash(k) % block_size) + 1 -- 获取hash值
if self.can_each then
block_size = block_size * 2
hash_code = hash_code * 2
end
-- 计算实际占用空间
block_size = block_size * addr_size
-- 计算指针实际位置
hash_code = hash_code * addr_size
local level = 0
while true do
local po = (level * block_size) + hash_code
local fm = self.fm
fm:seek('set', po)
local addr1 = fm:read(addr_size)
if addr1 then
addr1 = unpack(self.F.A, addr1)
else
addr1 = 0
end
if addr1 == 0 then
break
end
local next_addr = self:get_next_addr(addr1)
if next_addr == 0 then
-- 如果下一个地址无效,则将当前地址设置为0
fm:seek('set', po)
fm:write((pack(self.F.A, 0)))
else
-- 否则,更新当前地址的下一个地址
fm:seek('set', po + addr_size)
fm:write((pack(self.F.A, next_addr)))
end
level = level + 1 -- 下降深度
end
end
--- 获取下一个有效地址
---@param addr number 当前地址
---@return number 下一个有效地址
function db:get_next_addr(addr)
local fw = self.fw
fw:seek('set', addr + 8)
local next_addr = unpack(self.F.A, fw:read(self.addr_size))
return next_addr
end`
当调用db.del时似乎是伪删除 each函数会报错
Runtime error: db.lua:909: not enough memory for buffer allocation
stack traceback:
[C]: in method 'read'
db.lua:909: in for iterator 'for iterator'
以下是我尝试修改的del函数 但修改失败了 但实现了对于db文件和map文件部分清理 而且修改后each函数无法使用 可是本人太菜导致并未成功修复--- 删除成员
`---@param k any|LUADB_ID|LUADB_ADDR 成员key
---@return LuaDB
function db:del(k)
-- 申明变量
local F = self.F
local fw, fm = self.fw, self.fm
-- 得到成员属性
local po, addr, size, _, ck, level = self:check_key(k)
-- key转换类型,用于判断是否碰撞
k = tostring(k)
end
--- 更新成员指针链表中的指针
---@param k string 成员key
---@param addr number 被删除成员的地址
function db:update_pointers_after_delete(k, addr)
-- 更新成员指针链表中的指针
local block_size = self.block_size
local addr_size = self.addr_size
local hash_code = (hash(k) % block_size) + 1 -- 获取hash值
if self.can_each then
block_size = block_size * 2
hash_code = hash_code * 2
end
-- 计算实际占用空间
block_size = block_size * addr_size
-- 计算指针实际位置
hash_code = hash_code * addr_size
end
--- 清理成员指针链表
---@return LuaDB
function db:cleanup_pointers()
-- 遍历成员指针链表,清理无效的指针
local block_size = self.block_size
local addr_size = self.addr_size
local hash_code = (hash(k) % block_size) + 1 -- 获取hash值
if self.can_each then
block_size = block_size * 2
hash_code = hash_code * 2
end
-- 计算实际占用空间
block_size = block_size * addr_size
-- 计算指针实际位置
hash_code = hash_code * addr_size
end
--- 获取下一个有效地址
---@param addr number 当前地址
---@return number 下一个有效地址
function db:get_next_addr(addr)
local fw = self.fw
fw:seek('set', addr + 8)
local next_addr = unpack(self.F.A, fw:read(self.addr_size))
return next_addr
end`