]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Add and implement setting max_clearobjects_extra_loaded_blocks.
authorKahrl <kahrl@gmx.net>
Sun, 2 Jun 2013 13:35:29 +0000 (15:35 +0200)
committerKahrl <kahrl@gmx.net>
Mon, 3 Jun 2013 18:09:32 +0000 (20:09 +0200)
Now Environment::clearAllObjects() unloads unused blocks in an interval
defined by max_clearobjects_extra_loaded_blocks (default 4096).

minetest.conf.example
src/defaultsettings.cpp
src/environment.cpp
src/map.cpp
src/map.h

index af75438ff40f9a95337998ac2100e8c2d8c8538b..4fd443db784e901c49b054afd475cc64a2c2bdb7 100644 (file)
 #max_block_send_distance = 10
 # From how far blocks are generated for clients (value * 16 nodes)
 #max_block_generate_distance = 6
+# Number of extra blocks that can be loaded by /clearobjects at once
+# This is a trade-off between sqlite transaction overhead and
+# memory consumption (4096=100MB, as a rule of thumb)
+#max_clearobjects_extra_loaded_blocks = 4096
 # Interval of sending time of day to clients
 #time_send_interval = 5
 # Length of day/night cycle. 72=20min, 360=4min, 1=24hour, 0=day/night/whatever stays unchanged
index f270a47aa4d175d5b36818a70313a820294065c2..d2bed7ed89c3703895e3d8b9ddfb52776bf9da36 100644 (file)
@@ -175,6 +175,7 @@ void set_default_settings(Settings *settings)
        settings->setDefault("max_simultaneous_block_sends_server_total", "20");
        settings->setDefault("max_block_send_distance", "9");
        settings->setDefault("max_block_generate_distance", "7");
+       settings->setDefault("max_clearobjects_extra_loaded_blocks", "4096");
        settings->setDefault("time_send_interval", "5");
        settings->setDefault("time_speed", "72");
        settings->setDefault("server_unload_unused_data_timeout", "29");
index 83ae590149937e7a8cf5cb9050bb245cbf0cf8f6..ab6a6d3d345bcf92bb8d8334eea6f9ab5bed94ec 100644 (file)
@@ -945,6 +945,16 @@ void ServerEnvironment::clearAllObjects()
                m_active_objects.erase(*i);
        }
 
+       // Get list of loaded blocks
+       std::list<v3s16> loaded_blocks;
+       infostream<<"ServerEnvironment::clearAllObjects(): "
+                       <<"Listing all loaded blocks"<<std::endl;
+       m_map->listAllLoadedBlocks(loaded_blocks);
+       infostream<<"ServerEnvironment::clearAllObjects(): "
+                       <<"Done listing all loaded blocks: "
+                       <<loaded_blocks.size()<<std::endl;
+
+       // Get list of loadable blocks
        std::list<v3s16> loadable_blocks;
        infostream<<"ServerEnvironment::clearAllObjects(): "
                        <<"Listing all loadable blocks"<<std::endl;
@@ -953,6 +963,20 @@ void ServerEnvironment::clearAllObjects()
                        <<"Done listing all loadable blocks: "
                        <<loadable_blocks.size()
                        <<", now clearing"<<std::endl;
+
+       // Grab a reference on each loaded block to avoid unloading it
+       for(std::list<v3s16>::iterator i = loaded_blocks.begin();
+                       i != loaded_blocks.end(); ++i)
+       {
+               v3s16 p = *i;
+               MapBlock *block = m_map->getBlockNoCreateNoEx(p);
+               assert(block);
+               block->refGrab();
+       }
+
+       // Remove objects in all loadable blocks
+       u32 unload_interval = g_settings->getS32("max_clearobjects_extra_loaded_blocks");
+       unload_interval = MYMAX(unload_interval, 1);
        u32 report_interval = loadable_blocks.size() / 10;
        u32 num_blocks_checked = 0;
        u32 num_blocks_cleared = 0;
@@ -987,7 +1011,22 @@ void ServerEnvironment::clearAllObjects()
                                        <<" in "<<num_blocks_cleared<<" blocks ("
                                        <<percent<<"%)"<<std::endl;
                }
+               if(num_blocks_checked % unload_interval == 0){
+                       m_map->unloadUnreferencedBlocks();
+               }
        }
+       m_map->unloadUnreferencedBlocks();
+
+       // Drop references that were added above
+       for(std::list<v3s16>::iterator i = loaded_blocks.begin();
+                       i != loaded_blocks.end(); ++i)
+       {
+               v3s16 p = *i;
+               MapBlock *block = m_map->getBlockNoCreateNoEx(p);
+               assert(block);
+               block->refDrop();
+       }
+
        infostream<<"ServerEnvironment::clearAllObjects(): "
                        <<"Finished: Cleared "<<num_objs_cleared<<" objects"
                        <<" in "<<num_blocks_cleared<<" blocks"<<std::endl;
index 43502253b14121b2aa3fb12e9f5e9af64f221cdb..7439076d37c54f0fbf0ebe5739d51a383a24fee4 100644 (file)
@@ -1510,6 +1510,11 @@ void Map::timerUpdate(float dtime, float unload_timeout,
        }
 }
 
+void Map::unloadUnreferencedBlocks(std::list<v3s16> *unloaded_blocks)
+{
+       timerUpdate(0.0, -1.0, unloaded_blocks);
+}
+
 void Map::deleteSectors(std::list<v2s16> &list)
 {
        for(std::list<v2s16>::iterator j = list.begin();
@@ -3409,6 +3414,26 @@ void ServerMap::listAllLoadableBlocks(std::list<v3s16> &dst)
        }
 }
 
+void ServerMap::listAllLoadedBlocks(std::list<v3s16> &dst)
+{
+       for(std::map<v2s16, MapSector*>::iterator si = m_sectors.begin();
+               si != m_sectors.end(); ++si)
+       {
+               MapSector *sector = si->second;
+
+               std::list<MapBlock*> blocks;
+               sector->getBlocks(blocks);
+
+               for(std::list<MapBlock*>::iterator i = blocks.begin();
+                               i != blocks.end(); ++i)
+               {
+                       MapBlock *block = (*i);
+                       v3s16 p = block->getPos();
+                       dst.push_back(p);
+               }
+       }
+}
+
 void ServerMap::saveMapMeta()
 {
        DSTACK(__FUNCTION_NAME);
index 31001e4c397b9342a430671bf2e85d4f668b00a6..530d81e7a72a646df488bd6316a96f86976a81b9 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -279,6 +279,12 @@ class Map /*: public NodeContainer*/
        void timerUpdate(float dtime, float unload_timeout,
                        std::list<v3s16> *unloaded_blocks=NULL);
 
+       /*
+               Unloads all blocks with a zero refCount().
+               Saves modified blocks before unloading on MAPTYPE_SERVER.
+       */
+       void unloadUnreferencedBlocks(std::list<v3s16> *unloaded_blocks=NULL);
+
        // Deletes sectors and their blocks from memory
        // Takes cache into account
        // If deleted sector is in sector cache, clears cache
@@ -433,8 +439,8 @@ class ServerMap : public Map
        void endSave();
 
        void save(ModifiedState save_level);
-       //void loadAll();
        void listAllLoadableBlocks(std::list<v3s16> &dst);
+       void listAllLoadedBlocks(std::list<v3s16> &dst);
        // Saves map seed and possibly other stuff
        void saveMapMeta();
        void loadMapMeta();