gpt4 book ai didi

Lua 表作为数据库的前端

转载 作者:IT王子 更新时间:2023-10-29 06:14:19 25 4
gpt4 key购买 nike

我正在尝试将数据库实现为 Lua 表。使用元表,该表将是空的,当请求或修改表中的项目时,它将返回或修改数据库中的项目。数据库本身永远不会加载到内存中,除了被请求的部分。程序应该将其作为表格进行交互(因为它是表格)。该表,因为它只是一个“前端”,会将修改后的数据保存到数据库中(而不是在表中定义该项目)。

在里面没有表格的表格中,这很容易实现。我试图让它与无限深度的多层表一起工作。(旁白:我正在考虑的数据库是 redis。理想情况下,只需更改基本操作语法,就可以为任何数据库或类似数据库的服务器实现。)

由于 Lua 元表的行为,__newindex 方法仅在顶层修改某些内容(或创建,如果您使用代理)时使用。 __index 方法在读取某些内容时被调用,即使该调用是为了修改子表中的某些内容。正因为如此,我正在尝试编写一个 __index 方法,当请求一个表时,它返回另一个具有相同行为的伪代理(一个表代理数据库而不是另一个表),除了代理是针对顶层内的表/数组/列表等,深度不确定。我在挣扎。

我的问题是:

  • 以前实现过吗?
  • 我应该关注“适当的”吗类系统而不是我现在正在做的?

最佳答案

当你创建一个表时,只需在假表中添加一个空表并设置它的元表:

local fake = {}
do
local lookup = {} --Will be using this to avoid using lots of metatables

local real = {}

local meta
meta = {
__index = function(self,i)
return rawget(lookup[self], i)
end,
__newindex = function(self,i,v)
rawset(lookup[self], i, v)
if type(v) == "table" then
rawset(self, i, setmetatable({},meta))
lookup[self[i]] = v
end
end
}

setmetatable(fake, meta)
lookup[fake] = real
end

fake[1] = "hello"
print(fake[1])
print(rawget(fake, 1))
fake.x = {"hi"}
print(fake.x)
print(rawget(fake, 'x')) --This still prints a table because there actually is one, but in reality it's abiding by our rules
print(fake.x[1])
print(rawget(fake.x, 1))
fake.x.y = "aha"
print(fake.x.y)
print(rawget(fake.x, 'y'))

此方法唯一需要注意的是他们可以像这样直接修改数据库:

fake.myvalue = {}
fake.myvalue = 5

另一种方法是边走边换行:

local fake = {}
do
local lookup = {} --Will be using this to avoid using lots of metatables
local cache = {} --will be using to avoid usings tons of new objects

local real = {}

local meta
meta = {
__index = function(self,i)
local val = rawget(lookup[self], i)
if type(val) == "table" then
if cache[val] then
return cache[val]
else
local faker = {}
lookup[faker] = val
cache[val] = faker
return setmetatable(faker, meta)
end
else
return val
end
end,
__newindex = function(self,i,v)
rawset(lookup[self], i, v)
end
}

setmetatable(fake, meta)
lookup[fake] = real
end

fake[1] = "hello"
print(fake[1])
print(rawget(fake, 1))

fake.x = {"hi"}
print(fake.x)
print(rawget(fake, 'x')) --This still prints a table because there actually is one, but in reality it's abiding by our rules
print(fake.x[1])
print(rawget(fake.x, 1))
fake.x.y = "aha"
print(fake.x.y)
print(rawget(fake.x, 'y'))

这样就完全避免了直接修改问题

关于Lua 表作为数据库的前端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35666834/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com