Don't rapid-fire unsuspend rechecks on unloaded
If a node couldn't be checked for falling due to it having an unloaded area below it, we were kicking it back into the queue for immediate recheck on the next step, which caused us to often process a batch every step when those nodes were in a stable unloaded state. Instead, kick them to a time deferred queue that gets merged back into the main queue only every 2 seconds. This should cut down on how many times we have to keep reshuffling the batch and garbage-collecting old batch tables.
This commit is contained in:
parent
e6ed5bf166
commit
b9e5d480fe
@ -18,8 +18,12 @@ minetest.after(0, function()
|
||||
end)
|
||||
|
||||
local hash = minetest.hash_node_position
|
||||
|
||||
local pending = {}
|
||||
local function pend(pos) pending[hash(pos)] = pos end
|
||||
local function pend(pos)
|
||||
if not pos.hash then pos.hash = hash(pos) end
|
||||
pending[pos.hash] = pos
|
||||
end
|
||||
|
||||
local function toomanyents()
|
||||
local entqty = 0
|
||||
@ -34,6 +38,24 @@ end
|
||||
local batch = {}
|
||||
local batchpos = 1
|
||||
|
||||
local defer
|
||||
do
|
||||
local deferred
|
||||
defer = function(pos)
|
||||
if not deferred then
|
||||
deferred = {}
|
||||
minetest.after(2, function()
|
||||
for k, v in pairs(deferred) do
|
||||
pending[k] = v
|
||||
end
|
||||
deferred = nil
|
||||
end)
|
||||
end
|
||||
if not pos.hash then pos.hash = hash(pos) end
|
||||
deferred[pos.hash] = pos
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
if toomanyents() then return end
|
||||
local stop = minetest.get_us_time() + max_time_per_step * 1000000
|
||||
@ -42,9 +64,7 @@ minetest.register_globalstep(function()
|
||||
for _, v in pairs(pending) do batch[#batch + 1] = v end
|
||||
for i = #batch, 2, -1 do
|
||||
local j = math_random(1, i)
|
||||
local x = batch[i]
|
||||
batch[i] = batch[j]
|
||||
batch[j] = x
|
||||
batch[i], batch[j] = batch[j], batch[i]
|
||||
end
|
||||
batchpos = 1
|
||||
pending = {}
|
||||
@ -55,7 +75,7 @@ minetest.register_globalstep(function()
|
||||
if not pending[hash(bpos)] then
|
||||
local bnode = minetest.get_node_or_nil(bpos)
|
||||
if not bnode then
|
||||
pend(pos)
|
||||
defer(pos)
|
||||
elseif fallthru[bnode.name] then
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name ~= bnode.name then
|
||||
|
Loading…
x
Reference in New Issue
Block a user