@@ -76,7 +76,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
76
76
Map::Map (std::ostream &dout, IGameDef *gamedef):
77
77
m_dout(dout),
78
78
m_gamedef(gamedef),
79
- m_sector_cache(NULL )
79
+ m_sector_cache(NULL ),
80
+ m_transforming_liquid_loop_count_multiplier(1 .0f ),
81
+ m_unprocessed_count(0 ),
82
+ m_inc_trending_up_start_time(0 ),
83
+ m_queue_size_timer_started(false )
80
84
{
81
85
}
82
86
@@ -1611,6 +1615,7 @@ s32 Map::transforming_liquid_size() {
1611
1615
1612
1616
void Map::transformLiquids (std::map<v3s16, MapBlock*> & modified_blocks)
1613
1617
{
1618
+
1614
1619
INodeDefManager *nodemgr = m_gamedef->ndef ();
1615
1620
1616
1621
DSTACK (__FUNCTION_NAME);
@@ -1619,6 +1624,8 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks)
1619
1624
u32 loopcount = 0 ;
1620
1625
u32 initial_size = m_transforming_liquid.size ();
1621
1626
1627
+ u32 curr_time = getTime (PRECISION_MILLI);
1628
+
1622
1629
/* if(initial_size != 0)
1623
1630
infostream<<"transformLiquids(): initial_size="<<initial_size<<std::endl;*/
1624
1631
@@ -1628,7 +1635,27 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks)
1628
1635
// List of MapBlocks that will require a lighting update (due to lava)
1629
1636
std::map<v3s16, MapBlock*> lighting_modified_blocks;
1630
1637
1631
- u16 loop_max = g_settings->getU16 (" liquid_loop_max" );
1638
+ u32 liquid_loop_max = g_settings->getS32 (" liquid_loop_max" );
1639
+ u32 loop_max = liquid_loop_max;
1640
+
1641
+ // std::cout << "transformLiquids(): loopmax initial="
1642
+ // << loop_max * m_transforming_liquid_loop_count_multiplier;
1643
+
1644
+ // If liquid_loop_max is not keeping up with the queue size increase
1645
+ // loop_max up to a maximum of liquid_loop_max * dedicated_server_step.
1646
+ if (m_transforming_liquid.size () > loop_max * 2 ) {
1647
+ // "Burst" mode
1648
+ float server_step = g_settings->getFloat (" dedicated_server_step" );
1649
+ if (m_transforming_liquid_loop_count_multiplier - 1.0 < server_step)
1650
+ m_transforming_liquid_loop_count_multiplier *= 1.0 + server_step / 10 ;
1651
+ } else {
1652
+ m_transforming_liquid_loop_count_multiplier = 1.0 ;
1653
+ }
1654
+
1655
+ loop_max *= m_transforming_liquid_loop_count_multiplier;
1656
+
1657
+ // std::cout << " queue sz=" << m_transforming_liquid.size()
1658
+ // << " loop_max=" << loop_max;
1632
1659
1633
1660
while (m_transforming_liquid.size () != 0 )
1634
1661
{
@@ -1884,6 +1911,54 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks)
1884
1911
while (must_reflow.size () > 0 )
1885
1912
m_transforming_liquid.push_back (must_reflow.pop_front ());
1886
1913
updateLighting (lighting_modified_blocks, modified_blocks);
1914
+
1915
+
1916
+ /*
1917
+ * Queue size limiting
1918
+ */
1919
+ u32 prev_unprocessed = m_unprocessed_count;
1920
+ m_unprocessed_count = m_transforming_liquid.size ();
1921
+
1922
+ // if unprocessed block count is decreasing or stable
1923
+ if (m_unprocessed_count <= prev_unprocessed) {
1924
+ m_queue_size_timer_started = false ;
1925
+ } else {
1926
+ if (!m_queue_size_timer_started)
1927
+ m_inc_trending_up_start_time = curr_time;
1928
+ m_queue_size_timer_started = true ;
1929
+ }
1930
+
1931
+ u16 time_until_purge = g_settings->getU16 (" liquid_queue_purge_time" );
1932
+ time_until_purge *= 1000 ; // seconds -> milliseconds
1933
+
1934
+ // std::cout << " growing for: "
1935
+ // << (m_queue_size_timer_started ? curr_time - m_inc_trend_up_start_time : 0)
1936
+ // << "ms" << std::endl;
1937
+
1938
+ // Account for curr_time overflowing
1939
+ if (m_queue_size_timer_started && m_inc_trending_up_start_time > curr_time)
1940
+ m_queue_size_timer_started = false ;
1941
+
1942
+ /* If the queue has been growing for more than liquid_queue_purge_time seconds
1943
+ * and the number of unprocessed blocks is still > liquid_loop_max then we
1944
+ * cannot keep up; dump the oldest blocks from the queue so that the queue
1945
+ * has liquid_loop_max items in it
1946
+ */
1947
+ if (m_queue_size_timer_started
1948
+ && curr_time - m_inc_trending_up_start_time > time_until_purge
1949
+ && m_unprocessed_count > liquid_loop_max) {
1950
+
1951
+ size_t dump_qty = m_unprocessed_count - liquid_loop_max;
1952
+
1953
+ infostream << " transformLiquids(): DUMPING " << dump_qty
1954
+ << " blocks from the queue" << std::endl;
1955
+
1956
+ while (dump_qty--)
1957
+ m_transforming_liquid.pop_front ();
1958
+
1959
+ m_queue_size_timer_started = false ; // optimistically assume we can keep up now
1960
+ m_unprocessed_count = m_transforming_liquid.size ();
1961
+ }
1887
1962
}
1888
1963
1889
1964
NodeMetadata *Map::getNodeMetadata (v3s16 p)
0 commit comments