mirror of
https://github.com/minetest/minetest.git
synced 2024-11-23 16:13:46 +01:00
Do not allow the m_transforming_liquid queue to increase until all RAM is consumed
This commit is contained in:
parent
3b902fd574
commit
082256a9f8
@ -100,6 +100,9 @@
|
|||||||
#new_style_water = false
|
#new_style_water = false
|
||||||
# Max liquids processed per step
|
# Max liquids processed per step
|
||||||
#liquid_loop_max = 10000
|
#liquid_loop_max = 10000
|
||||||
|
# The time (in seconds) that the liquids queue may grow beyond processing
|
||||||
|
# capacity until an attempt is made to decrease its size by dumping old queue items
|
||||||
|
#liquid_queue_purge_time = 30
|
||||||
# Update liquids every .. recommend for finite: 0.2
|
# Update liquids every .. recommend for finite: 0.2
|
||||||
#liquid_update = 1.0
|
#liquid_update = 1.0
|
||||||
# Enable nice leaves; disable for speed
|
# Enable nice leaves; disable for speed
|
||||||
|
@ -277,6 +277,7 @@ void set_default_settings(Settings *settings)
|
|||||||
|
|
||||||
//liquid stuff
|
//liquid stuff
|
||||||
settings->setDefault("liquid_loop_max", "10000");
|
settings->setDefault("liquid_loop_max", "10000");
|
||||||
|
settings->setDefault("liquid_queue_purge_time", "30");
|
||||||
settings->setDefault("liquid_update", "1.0");
|
settings->setDefault("liquid_update", "1.0");
|
||||||
|
|
||||||
//mapgen stuff
|
//mapgen stuff
|
||||||
|
79
src/map.cpp
79
src/map.cpp
@ -76,7 +76,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
Map::Map(std::ostream &dout, IGameDef *gamedef):
|
Map::Map(std::ostream &dout, IGameDef *gamedef):
|
||||||
m_dout(dout),
|
m_dout(dout),
|
||||||
m_gamedef(gamedef),
|
m_gamedef(gamedef),
|
||||||
m_sector_cache(NULL)
|
m_sector_cache(NULL),
|
||||||
|
m_transforming_liquid_loop_count_multiplier(1.0f),
|
||||||
|
m_unprocessed_count(0),
|
||||||
|
m_inc_trending_up_start_time(0),
|
||||||
|
m_queue_size_timer_started(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1611,6 +1615,7 @@ s32 Map::transforming_liquid_size() {
|
|||||||
|
|
||||||
void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks)
|
void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks)
|
||||||
{
|
{
|
||||||
|
|
||||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||||
|
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
@ -1619,6 +1624,8 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks)
|
|||||||
u32 loopcount = 0;
|
u32 loopcount = 0;
|
||||||
u32 initial_size = m_transforming_liquid.size();
|
u32 initial_size = m_transforming_liquid.size();
|
||||||
|
|
||||||
|
u32 curr_time = getTime(PRECISION_MILLI);
|
||||||
|
|
||||||
/*if(initial_size != 0)
|
/*if(initial_size != 0)
|
||||||
infostream<<"transformLiquids(): initial_size="<<initial_size<<std::endl;*/
|
infostream<<"transformLiquids(): initial_size="<<initial_size<<std::endl;*/
|
||||||
|
|
||||||
@ -1628,7 +1635,27 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks)
|
|||||||
// List of MapBlocks that will require a lighting update (due to lava)
|
// List of MapBlocks that will require a lighting update (due to lava)
|
||||||
std::map<v3s16, MapBlock*> lighting_modified_blocks;
|
std::map<v3s16, MapBlock*> lighting_modified_blocks;
|
||||||
|
|
||||||
u16 loop_max = g_settings->getU16("liquid_loop_max");
|
u32 liquid_loop_max = g_settings->getS32("liquid_loop_max");
|
||||||
|
u32 loop_max = liquid_loop_max;
|
||||||
|
|
||||||
|
// std::cout << "transformLiquids(): loopmax initial="
|
||||||
|
// << loop_max * m_transforming_liquid_loop_count_multiplier;
|
||||||
|
|
||||||
|
// If liquid_loop_max is not keeping up with the queue size increase
|
||||||
|
// loop_max up to a maximum of liquid_loop_max * dedicated_server_step.
|
||||||
|
if (m_transforming_liquid.size() > loop_max * 2) {
|
||||||
|
// "Burst" mode
|
||||||
|
float server_step = g_settings->getFloat("dedicated_server_step");
|
||||||
|
if (m_transforming_liquid_loop_count_multiplier - 1.0 < server_step)
|
||||||
|
m_transforming_liquid_loop_count_multiplier *= 1.0 + server_step / 10;
|
||||||
|
} else {
|
||||||
|
m_transforming_liquid_loop_count_multiplier = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
loop_max *= m_transforming_liquid_loop_count_multiplier;
|
||||||
|
|
||||||
|
// std::cout << " queue sz=" << m_transforming_liquid.size()
|
||||||
|
// << " loop_max=" << loop_max;
|
||||||
|
|
||||||
while(m_transforming_liquid.size() != 0)
|
while(m_transforming_liquid.size() != 0)
|
||||||
{
|
{
|
||||||
@ -1884,6 +1911,54 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks)
|
|||||||
while (must_reflow.size() > 0)
|
while (must_reflow.size() > 0)
|
||||||
m_transforming_liquid.push_back(must_reflow.pop_front());
|
m_transforming_liquid.push_back(must_reflow.pop_front());
|
||||||
updateLighting(lighting_modified_blocks, modified_blocks);
|
updateLighting(lighting_modified_blocks, modified_blocks);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Queue size limiting
|
||||||
|
*/
|
||||||
|
u32 prev_unprocessed = m_unprocessed_count;
|
||||||
|
m_unprocessed_count = m_transforming_liquid.size();
|
||||||
|
|
||||||
|
// if unprocessed block count is decreasing or stable
|
||||||
|
if (m_unprocessed_count <= prev_unprocessed) {
|
||||||
|
m_queue_size_timer_started = false;
|
||||||
|
} else {
|
||||||
|
if (!m_queue_size_timer_started)
|
||||||
|
m_inc_trending_up_start_time = curr_time;
|
||||||
|
m_queue_size_timer_started = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 time_until_purge = g_settings->getU16("liquid_queue_purge_time");
|
||||||
|
time_until_purge *= 1000; // seconds -> milliseconds
|
||||||
|
|
||||||
|
// std::cout << " growing for: "
|
||||||
|
// << (m_queue_size_timer_started ? curr_time - m_inc_trend_up_start_time : 0)
|
||||||
|
// << "ms" << std::endl;
|
||||||
|
|
||||||
|
// Account for curr_time overflowing
|
||||||
|
if (m_queue_size_timer_started && m_inc_trending_up_start_time > curr_time)
|
||||||
|
m_queue_size_timer_started = false;
|
||||||
|
|
||||||
|
/* If the queue has been growing for more than liquid_queue_purge_time seconds
|
||||||
|
* and the number of unprocessed blocks is still > liquid_loop_max then we
|
||||||
|
* cannot keep up; dump the oldest blocks from the queue so that the queue
|
||||||
|
* has liquid_loop_max items in it
|
||||||
|
*/
|
||||||
|
if (m_queue_size_timer_started
|
||||||
|
&& curr_time - m_inc_trending_up_start_time > time_until_purge
|
||||||
|
&& m_unprocessed_count > liquid_loop_max) {
|
||||||
|
|
||||||
|
size_t dump_qty = m_unprocessed_count - liquid_loop_max;
|
||||||
|
|
||||||
|
infostream << "transformLiquids(): DUMPING " << dump_qty
|
||||||
|
<< " blocks from the queue" << std::endl;
|
||||||
|
|
||||||
|
while (dump_qty--)
|
||||||
|
m_transforming_liquid.pop_front();
|
||||||
|
|
||||||
|
m_queue_size_timer_started = false; // optimistically assume we can keep up now
|
||||||
|
m_unprocessed_count = m_transforming_liquid.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeMetadata *Map::getNodeMetadata(v3s16 p)
|
NodeMetadata *Map::getNodeMetadata(v3s16 p)
|
||||||
|
@ -366,6 +366,12 @@ protected:
|
|||||||
|
|
||||||
// Queued transforming water nodes
|
// Queued transforming water nodes
|
||||||
UniqueQueue<v3s16> m_transforming_liquid;
|
UniqueQueue<v3s16> m_transforming_liquid;
|
||||||
|
|
||||||
|
private:
|
||||||
|
f32 m_transforming_liquid_loop_count_multiplier;
|
||||||
|
u32 m_unprocessed_count;
|
||||||
|
u32 m_inc_trending_up_start_time; // milliseconds
|
||||||
|
bool m_queue_size_timer_started;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user