127 lines
2.9 KiB
Lua
127 lines
2.9 KiB
Lua
--[[
|
|
|
|
TechAge
|
|
=======
|
|
|
|
Copyright (C) 2019 Joachim Stolberg
|
|
|
|
GPL v3
|
|
See LICENSE.txt for more information
|
|
|
|
Memory storage system for volatile and non-volatile memory.
|
|
Non-volatile memory is stored from time to time and at shutdown
|
|
as node metadata. Volatile memory is lost at every shutdown.
|
|
|
|
]]--
|
|
|
|
local NUM_NODES_PER_MIN = 100
|
|
local NvmStore = {}
|
|
local MemStore = {}
|
|
local NumNodes = 0
|
|
local StoredNodes = 0
|
|
|
|
local function set_metadata(hash, tbl)
|
|
local pos = minetest.get_position_from_hash(hash)
|
|
local data = minetest.serialize(tbl)
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string("ta_data", data)
|
|
meta:mark_as_private("ta_data")
|
|
end
|
|
|
|
local function get_metadata(hash)
|
|
local pos = minetest.get_position_from_hash(hash)
|
|
local meta = minetest.get_meta(pos)
|
|
local s = meta:get_string("ta_data")
|
|
if s ~= "" then
|
|
return minetest.deserialize(s)
|
|
end
|
|
end
|
|
|
|
local function storage_loop()
|
|
local cnt = 0
|
|
while true do
|
|
NumNodes = 0
|
|
StoredNodes = 0
|
|
for hash,tbl in pairs(NvmStore) do
|
|
NumNodes = NumNodes + 1
|
|
if tbl.__used__ then
|
|
tbl.__used__ = nil
|
|
set_metadata(hash, tbl)
|
|
StoredNodes = StoredNodes + 1
|
|
cnt = cnt + 1
|
|
if cnt > NUM_NODES_PER_MIN then
|
|
cnt = 0
|
|
coroutine.yield()
|
|
end
|
|
else
|
|
-- remove from memory if node is unloaded
|
|
local pos = minetest.get_position_from_hash(hash)
|
|
if minetest.get_node(pos).name == "ignore" then
|
|
NvmStore[hash] = nil
|
|
MemStore[hash] = nil
|
|
end
|
|
end
|
|
end
|
|
coroutine.yield()
|
|
end
|
|
end
|
|
|
|
local co = coroutine.create(storage_loop)
|
|
|
|
|
|
local function cyclic_task()
|
|
local t = minetest.get_us_time()
|
|
coroutine.resume(co)
|
|
t = minetest.get_us_time() - t
|
|
print("[TA NVM Storage] duration="..t.."us, total="..NumNodes..", stored="..StoredNodes)
|
|
-- run every minutes
|
|
minetest.after(60, cyclic_task)
|
|
end
|
|
|
|
minetest.register_on_shutdown(function()
|
|
NumNodes = 0
|
|
StoredNodes = 0
|
|
local t = minetest.get_us_time()
|
|
for k,v in pairs(NvmStore) do
|
|
NumNodes = NumNodes + 1
|
|
if v.__used__ then
|
|
v.__used__ = nil
|
|
set_metadata(k, v)
|
|
StoredNodes = StoredNodes + 1
|
|
end
|
|
end
|
|
t = minetest.get_us_time() - t
|
|
print("[TA NVM Storage] duration="..t.."us, total="..NumNodes..", stored="..StoredNodes)
|
|
end)
|
|
|
|
minetest.after(60, cyclic_task)
|
|
|
|
|
|
-- To get the volatile node data as table
|
|
function techage.get_mem(pos, will_change)
|
|
local hash = minetest.hash_node_position(pos)
|
|
if not MemStore[hash] then
|
|
MemStore[hash] = {}
|
|
end
|
|
return MemStore[hash]
|
|
end
|
|
|
|
-- To get the nonvolatile node data as table
|
|
function techage.get_nvm(pos)
|
|
local hash = minetest.hash_node_position(pos)
|
|
if not NvmStore[hash] then
|
|
NvmStore[hash] = get_metadata(hash) or {}
|
|
end
|
|
NvmStore[hash].__used__ = true
|
|
return NvmStore[hash]
|
|
end
|
|
|
|
-- To be called when a node is removed
|
|
function techage.del_mem(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string("ta_data", "")
|
|
local hash = minetest.hash_node_position(pos)
|
|
NvmStore[hash] = nil
|
|
MemStore[hash] = nil
|
|
end
|