mirror of
https://github.com/joe7575/techpack.git
synced 2024-08-21 13:44:13 +02:00
data structures improvements
This commit is contained in:
parent
b6325f9078
commit
44c5285f28
@ -27,7 +27,7 @@ safer_lua.DataStructHelp = [[
|
|||||||
a.insert(5,7) --> {1,8,3,4,7,6}
|
a.insert(5,7) --> {1,8,3,4,7,6}
|
||||||
a.remove(3) --> {1,8,4,7,6}
|
a.remove(3) --> {1,8,4,7,6}
|
||||||
a.insert(1, "hello") --> {"hello",1,8,4,7,6}
|
a.insert(1, "hello") --> {"hello",1,8,4,7,6}
|
||||||
a.size() --> function returns 10
|
a.size() --> function returns 6
|
||||||
|
|
||||||
Unlike arrays, which are indexed by a range of numbers,
|
Unlike arrays, which are indexed by a range of numbers,
|
||||||
'stores' are indexed by keys:
|
'stores' are indexed by keys:
|
||||||
@ -37,7 +37,7 @@ safer_lua.DataStructHelp = [[
|
|||||||
s.get("val") --> returns 12
|
s.get("val") --> returns 12
|
||||||
s.set(0, "hello") --> {val = 12, [0] = "hello"}
|
s.set(0, "hello") --> {val = 12, [0] = "hello"}
|
||||||
s.del("val") --> {[0] = "hello"}
|
s.del("val") --> {[0] = "hello"}
|
||||||
s.size() --> function returns 6
|
s.size() --> function returns 1
|
||||||
|
|
||||||
A 'set' is an unordered collection with no duplicate
|
A 'set' is an unordered collection with no duplicate
|
||||||
elements.
|
elements.
|
||||||
@ -48,7 +48,7 @@ safer_lua.DataStructHelp = [[
|
|||||||
s.add("Susi") --> {Lucy = true, Susi = true}
|
s.add("Susi") --> {Lucy = true, Susi = true}
|
||||||
s.has("Susi") --> function returns `true`
|
s.has("Susi") --> function returns `true`
|
||||||
s.has("Mike") --> function returns `false`
|
s.has("Mike") --> function returns `false`
|
||||||
s.size() --> function returns 11
|
s.size() --> function returns 2
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local function var_count(v)
|
local function var_count(v)
|
||||||
@ -61,7 +61,7 @@ local function var_count(v)
|
|||||||
elseif type(v) == "string" then
|
elseif type(v) == "string" then
|
||||||
return #v
|
return #v
|
||||||
elseif type(v) == "table" then
|
elseif type(v) == "table" then
|
||||||
return v.size()
|
return v.memsize()
|
||||||
else
|
else
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
@ -70,11 +70,12 @@ end
|
|||||||
|
|
||||||
function safer_lua.Store()
|
function safer_lua.Store()
|
||||||
|
|
||||||
local new_t = {__data__ = {}}
|
local new_t = {}
|
||||||
local mt = {}
|
local mt = {}
|
||||||
|
|
||||||
-- `all` will represent the number of both
|
local MemSize = 0
|
||||||
local Count = 0
|
local Size = 0
|
||||||
|
local Data = {}
|
||||||
|
|
||||||
mt.__newindex = function(t, k, v) return end
|
mt.__newindex = function(t, k, v) return end
|
||||||
|
|
||||||
@ -82,39 +83,55 @@ function safer_lua.Store()
|
|||||||
|
|
||||||
new_t.set = function(k,v)
|
new_t.set = function(k,v)
|
||||||
if type(k) == "number" then
|
if type(k) == "number" then
|
||||||
Count = Count - mt.count(rawget(new_t.__data__, k))
|
if rawget(Data, k) then -- has entry?
|
||||||
Count = Count + mt.count(v)
|
MemSize = MemSize - mt.count(rawget(Data, k))
|
||||||
rawset(new_t.__data__,k,v)
|
|
||||||
elseif type(k) == "string" then
|
|
||||||
if rawget(new_t.__data__, k) then -- has entry?
|
|
||||||
Count = Count - mt.count(rawget(new_t.__data__, k))
|
|
||||||
else
|
else
|
||||||
Count = Count + mt.count(k)
|
Size = Size + 1
|
||||||
end
|
end
|
||||||
Count = Count + mt.count(v)
|
MemSize = MemSize + mt.count(v)
|
||||||
rawset(new_t.__data__,k,v)
|
rawset(Data, k, v)
|
||||||
|
elseif type(k) == "string" then
|
||||||
|
if rawget(Data, k) then -- has entry?
|
||||||
|
MemSize = MemSize - mt.count(rawget(Data, k))
|
||||||
|
else
|
||||||
|
MemSize = MemSize + mt.count(k)
|
||||||
|
Size = Size + 1
|
||||||
|
end
|
||||||
|
MemSize = MemSize + mt.count(v)
|
||||||
|
rawset(Data, k, v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.get = function(k)
|
new_t.get = function(k)
|
||||||
return rawget(new_t.__data__, k)
|
return rawget(Data, k)
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.del = function(k)
|
new_t.del = function(k)
|
||||||
Count = Count - mt.count(k)
|
if rawget(Data, k) then -- has entry?
|
||||||
Count = Count - mt.count(rawget(new_t.__data__, k))
|
MemSize = MemSize - mt.count(k)
|
||||||
rawset(new_t.__data__,k,nil)
|
MemSize = MemSize - mt.count(rawget(Data, k))
|
||||||
|
rawset(Data, k, nil)
|
||||||
|
Size = Size - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
new_t.memsize = function(t)
|
||||||
|
return MemSize
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.size = function(t)
|
new_t.size = function(t)
|
||||||
return Count
|
return Size
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.dump = function(size)
|
new_t.__dump = function()
|
||||||
size = size or 200
|
-- remove the not serializable meta data
|
||||||
local s = dump(new_t.__data__)
|
return {Type = "Store", Size = Size, MemSize = MemSize, Data = Data}
|
||||||
if #s > size then s = s:sub(1, size).."..." end
|
end
|
||||||
return s
|
|
||||||
|
new_t.__load = function(size, memsize, data)
|
||||||
|
Size = size
|
||||||
|
MemSize = memsize
|
||||||
|
Data = data
|
||||||
end
|
end
|
||||||
|
|
||||||
return setmetatable(new_t, mt)
|
return setmetatable(new_t, mt)
|
||||||
@ -123,11 +140,11 @@ end
|
|||||||
|
|
||||||
function safer_lua.Array(...)
|
function safer_lua.Array(...)
|
||||||
|
|
||||||
local new_t = {__data__ = {}}
|
local new_t = {}
|
||||||
local mt = {}
|
local mt = {}
|
||||||
|
|
||||||
-- `all` will represent the number of both
|
local MemSize = 0
|
||||||
local Count = 0
|
local Data = {}
|
||||||
|
|
||||||
mt.__newindex = function(t, k, v) return end
|
mt.__newindex = function(t, k, v) return end
|
||||||
|
|
||||||
@ -137,45 +154,56 @@ function safer_lua.Array(...)
|
|||||||
local v = select(idx,...)
|
local v = select(idx,...)
|
||||||
local cnt = mt.count(v)
|
local cnt = mt.count(v)
|
||||||
if cnt then
|
if cnt then
|
||||||
Count = Count + cnt
|
MemSize = MemSize + cnt
|
||||||
rawset(new_t.__data__,idx, v)
|
rawset(Data, idx, v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.add = function(v)
|
new_t.add = function(v)
|
||||||
Count = Count + mt.count(v)
|
MemSize = MemSize + mt.count(v)
|
||||||
local i = #new_t.__data__ + 1
|
local i = #Data + 1
|
||||||
table.insert(new_t.__data__,i,v)
|
table.insert(Data, i, v)
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.set = function(i,v)
|
new_t.set = function(i,v)
|
||||||
i = math.min(#new_t.__data__, i)
|
i = math.min(#Data, i)
|
||||||
Count = Count - mt.count(rawget(new_t.__data__, i))
|
MemSize = MemSize - mt.count(rawget(Data, i))
|
||||||
Count = Count + mt.count(v)
|
MemSize = MemSize + mt.count(v)
|
||||||
rawset(new_t.__data__,i,v)
|
rawset(Data, i, v)
|
||||||
|
end
|
||||||
|
|
||||||
|
new_t.get = function(i)
|
||||||
|
return Data[i]
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.insert = function(i, v)
|
new_t.insert = function(i, v)
|
||||||
Count = Count + mt.count(v)
|
MemSize = MemSize + mt.count(v)
|
||||||
i = math.min(#new_t.__data__, i)
|
i = math.min(#Data, i)
|
||||||
table.insert(new_t.__data__,i,v)
|
table.insert(Data, i, v)
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.remove = function(i)
|
new_t.remove = function(i)
|
||||||
local v = table.remove(new_t.__data__,i)
|
local v = table.remove(Data, i)
|
||||||
Count = Count - mt.count(v)
|
MemSize = MemSize - mt.count(v)
|
||||||
return v
|
return v
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.size = function(t)
|
new_t.memsize = function(t)
|
||||||
return Count
|
return MemSize
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.dump = function(size)
|
new_t.size = function(t)
|
||||||
size = size or 200
|
return #Data
|
||||||
local s = dump(new_t.__data__)
|
end
|
||||||
if #s > size then s = s:sub(1, size).."..." end
|
|
||||||
return s
|
new_t.__dump = function()
|
||||||
|
-- remove the not serializable meta data
|
||||||
|
return {Type = "Array", MemSize = MemSize, Data = Data}
|
||||||
|
end
|
||||||
|
|
||||||
|
new_t.__load = function(memsize, data)
|
||||||
|
MemSize = memsize
|
||||||
|
Data = data
|
||||||
end
|
end
|
||||||
|
|
||||||
return setmetatable(new_t, mt)
|
return setmetatable(new_t, mt)
|
||||||
@ -184,11 +212,12 @@ end
|
|||||||
|
|
||||||
function safer_lua.Set(...)
|
function safer_lua.Set(...)
|
||||||
|
|
||||||
local new_t = {__data__ = {}}
|
local new_t = {}
|
||||||
local mt = {}
|
local mt = {}
|
||||||
|
|
||||||
-- `all` will represent the number of both
|
local MemSize = 0
|
||||||
local Count = 0
|
local Size = 0
|
||||||
|
local Data = {}
|
||||||
|
|
||||||
mt.__newindex = function(t, k, v) return end
|
mt.__newindex = function(t, k, v) return end
|
||||||
|
|
||||||
@ -198,35 +227,69 @@ function safer_lua.Set(...)
|
|||||||
local v = select(idx,...)
|
local v = select(idx,...)
|
||||||
local cnt = mt.count(v)
|
local cnt = mt.count(v)
|
||||||
if cnt then
|
if cnt then
|
||||||
Count = Count + cnt
|
MemSize = MemSize + cnt
|
||||||
rawset(new_t.__data__,v, true)
|
Size = Size + 1
|
||||||
|
rawset(Data, v, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.add = function(k)
|
new_t.add = function(k)
|
||||||
Count = Count + mt.count(k)
|
MemSize = MemSize + mt.count(k)
|
||||||
rawset(new_t.__data__,k, true)
|
rawset(Data, k, true)
|
||||||
|
Size = Size + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.del = function(k)
|
new_t.del = function(k)
|
||||||
Count = Count - mt.count(k)
|
MemSize = MemSize - mt.count(k)
|
||||||
rawset(new_t.__data__,k, nil)
|
rawset(Data, k, nil)
|
||||||
|
Size = Size - 1
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.has = function(k)
|
new_t.has = function(k)
|
||||||
return rawget(new_t.__data__, k) == true
|
return rawget(Data, k) == true
|
||||||
|
end
|
||||||
|
|
||||||
|
new_t.memsize = function(t)
|
||||||
|
return MemSize
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.size = function(t)
|
new_t.size = function(t)
|
||||||
return Count
|
return Size
|
||||||
end
|
end
|
||||||
|
|
||||||
new_t.dump = function(size)
|
new_t.__dump = function()
|
||||||
size = size or 200
|
-- remove the not serializable meta data
|
||||||
local s = dump(new_t.__data__)
|
return {Type = "Set", Size = Size, MemSize = MemSize, Data = Data}
|
||||||
if #s > size then s = s:sub(1, size).."..." end
|
end
|
||||||
return s
|
|
||||||
|
new_t.__load = function(size, memsize, data)
|
||||||
|
Size = size
|
||||||
|
MemSize = memsize
|
||||||
|
Data = data
|
||||||
end
|
end
|
||||||
|
|
||||||
return setmetatable(new_t, mt)
|
return setmetatable(new_t, mt)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- remove the not serializable meta data
|
||||||
|
function safer_lua.datastruct_to_table(ds)
|
||||||
|
return ds.__dump()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- add the not serializable meta data again
|
||||||
|
function safer_lua.table_to_datastruct(tbl)
|
||||||
|
if tbl.Type == "Store" then
|
||||||
|
local s = safer_lua.Store()
|
||||||
|
s.__load(tbl.Size, tbl.MemSize, tbl.Data)
|
||||||
|
return s
|
||||||
|
elseif tbl.Type == "Set" then
|
||||||
|
local s = safer_lua.Set()
|
||||||
|
s.__load(tbl.Size, tbl.MemSize, tbl.Data)
|
||||||
|
return s
|
||||||
|
elseif tbl.Type == "Array" then
|
||||||
|
local a = safer_lua.Array()
|
||||||
|
a.__load(tbl.MemSize, tbl.Data)
|
||||||
|
return a
|
||||||
|
end
|
||||||
|
end
|
@ -81,6 +81,8 @@ local InvalidKeywords = {
|
|||||||
["do"] = true,
|
["do"] = true,
|
||||||
["function"] = true,
|
["function"] = true,
|
||||||
["_G"] = true,
|
["_G"] = true,
|
||||||
|
["__load"] = true,
|
||||||
|
["__dump"] = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
local InvalidChars = {
|
local InvalidChars = {
|
||||||
|
@ -105,23 +105,34 @@ local function calc_size(v)
|
|||||||
return 0
|
return 0
|
||||||
elseif type(v) == "string" then
|
elseif type(v) == "string" then
|
||||||
return #v
|
return #v
|
||||||
|
elseif v.MemSize then
|
||||||
|
return v.MemSize
|
||||||
else
|
else
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function write_value(mem, key, value)
|
local function write_value(mem, key, item)
|
||||||
if mem and mem.size < SERVER_CAPA then
|
if mem and mem.size < SERVER_CAPA then
|
||||||
if value == nil then
|
if mem.data[key] then
|
||||||
mem.size = mem.size - calc_size(mem.data[key])
|
mem.size = mem.size - calc_size(mem.data[key])
|
||||||
else
|
|
||||||
mem.size = mem.size - calc_size(mem.data[key])
|
|
||||||
mem.size = mem.size + calc_size(value)
|
|
||||||
end
|
end
|
||||||
mem.data[key] = value
|
if type(item) == "table" then
|
||||||
|
item = safer_lua.datastruct_to_table(item)
|
||||||
|
end
|
||||||
|
mem.size = mem.size + calc_size(item)
|
||||||
|
mem.data[key] = item
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function read_value(mem, key)
|
||||||
|
local item = mem.data[key]
|
||||||
|
if type(item) == "table" then
|
||||||
|
item = safer_lua.table_to_datastruct(item)
|
||||||
|
end
|
||||||
|
return item
|
||||||
|
end
|
||||||
|
|
||||||
tubelib.register_node("sl_controller:server", {}, {
|
tubelib.register_node("sl_controller:server", {}, {
|
||||||
on_recv_message = function(pos, topic, payload)
|
on_recv_message = function(pos, topic, payload)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
@ -129,7 +140,7 @@ tubelib.register_node("sl_controller:server", {}, {
|
|||||||
local number = meta:get_string("number")
|
local number = meta:get_string("number")
|
||||||
local mem = tubelib.get_data(number, "memory") or DEFAULT_MEM
|
local mem = tubelib.get_data(number, "memory") or DEFAULT_MEM
|
||||||
if topic == "read" then
|
if topic == "read" then
|
||||||
return mem.data[payload]
|
return read_value(mem, payload)
|
||||||
elseif topic == "write" then
|
elseif topic == "write" then
|
||||||
write_value(mem, payload.key, payload.value)
|
write_value(mem, payload.key, payload.value)
|
||||||
tubelib.set_data(number, "memory", mem)
|
tubelib.set_data(number, "memory", mem)
|
||||||
@ -157,7 +168,7 @@ sl_controller.register_function("server_read", {
|
|||||||
|
|
||||||
sl_controller.register_action("server_write", {
|
sl_controller.register_action("server_write", {
|
||||||
cmnd = function(self, num, key, value)
|
cmnd = function(self, num, key, value)
|
||||||
if type(key) == "string" and type(value) == "string" or type(value) == "number" then
|
if type(key) == "string" then
|
||||||
tubelib.send_message(num, self.meta.owner, nil, "write", {key=key, value=value})
|
tubelib.send_message(num, self.meta.owner, nil, "write", {key=key, value=value})
|
||||||
else
|
else
|
||||||
self.error("Invalid server_write parameter")
|
self.error("Invalid server_write parameter")
|
||||||
@ -165,8 +176,8 @@ sl_controller.register_action("server_write", {
|
|||||||
end,
|
end,
|
||||||
help = " $server_write(num, key, value)\n"..
|
help = " $server_write(num, key, value)\n"..
|
||||||
" Store a value on the server under the key 'key'.\n"..
|
" Store a value on the server under the key 'key'.\n"..
|
||||||
" 'key' must be a string. 'value' can be\n"..
|
" 'key' must be a string. 'value' can be either a\n"..
|
||||||
" either a number or a string.\n"..
|
" number, string, boolean, nil or data structure.\n"..
|
||||||
' example: $server_write("0123", "state", state)'
|
' example: $server_write("0123", "state", state)'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user