fixed block unloading from memory (a better fix coming next)

This commit is contained in:
Perttu Ahola 2011-06-26 21:53:11 +03:00
parent d702a2c33b
commit 3fccc67eb7
8 changed files with 70 additions and 74 deletions

@ -333,16 +333,16 @@ void Client::step(float dtime)
true, &deleted_blocks);*/ true, &deleted_blocks);*/
// Delete whole sectors // Delete whole sectors
u32 num = m_env.getMap().unloadUnusedData m_env.getMap().unloadUnusedData
(delete_unused_sectors_timeout, (delete_unused_sectors_timeout,
false, &deleted_blocks); &deleted_blocks);
if(num > 0) if(deleted_blocks.size() > 0)
{ {
/*dstream<<DTIME<<"Client: Deleted blocks of "<<num /*dstream<<DTIME<<"Client: Deleted blocks of "<<num
<<" unused sectors"<<std::endl;*/ <<" unused sectors"<<std::endl;*/
dstream<<DTIME<<"Client: Deleted "<<num /*dstream<<DTIME<<"Client: Deleted "<<num
<<" unused sectors"<<std::endl; <<" unused sectors"<<std::endl;*/
/* /*
Send info to server Send info to server

@ -82,6 +82,7 @@ void set_default_settings()
g_settings.setDefault("default_password", ""); g_settings.setDefault("default_password", "");
g_settings.setDefault("default_privs", "build, shout"); g_settings.setDefault("default_privs", "build, shout");
g_settings.setDefault("profiler_print_interval", "0"); g_settings.setDefault("profiler_print_interval", "0");
g_settings.setDefault("enable_mapgen_debug_info", "false");
g_settings.setDefault("objectdata_interval", "0.2"); g_settings.setDefault("objectdata_interval", "0.2");
g_settings.setDefault("active_object_range", "2"); g_settings.setDefault("active_object_range", "2");

@ -801,6 +801,9 @@ void ServerEnvironment::step(float dtime)
MapBlock *block = m_map->getBlockNoCreateNoEx(p); MapBlock *block = m_map->getBlockNoCreateNoEx(p);
if(block==NULL) if(block==NULL)
continue; continue;
// Reset block usage timer
block->resetUsageTimer();
// Set current time as timestamp // Set current time as timestamp
block->setTimestampNoChangedFlag(m_game_time); block->setTimestampNoChangedFlag(m_game_time);

@ -1388,8 +1388,6 @@ bool Map::dayNightDiffed(v3s16 blockpos)
*/ */
void Map::timerUpdate(float dtime) void Map::timerUpdate(float dtime)
{ {
//JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
core::map<v2s16, MapSector*>::Iterator si; core::map<v2s16, MapSector*>::Iterator si;
si = m_sectors.getIterator(); si = m_sectors.getIterator();
@ -1407,38 +1405,27 @@ void Map::timerUpdate(float dtime)
} }
} }
void Map::deleteSectors(core::list<v2s16> &list, bool only_blocks) void Map::deleteSectors(core::list<v2s16> &list)
{ {
core::list<v2s16>::Iterator j; core::list<v2s16>::Iterator j;
for(j=list.begin(); j!=list.end(); j++) for(j=list.begin(); j!=list.end(); j++)
{ {
MapSector *sector = m_sectors[*j]; MapSector *sector = m_sectors[*j];
if(only_blocks) // If sector is in sector cache, remove it from there
{ if(m_sector_cache == sector)
sector->deleteBlocks(); m_sector_cache = NULL;
} // Remove from map and delete
else m_sectors.remove(*j);
{ delete sector;
/*
If sector is in sector cache, remove it from there
*/
if(m_sector_cache == sector)
{
m_sector_cache = NULL;
}
/*
Remove from map and delete
*/
m_sectors.remove(*j);
delete sector;
}
} }
} }
u32 Map::unloadUnusedData(float timeout, bool only_blocks, void Map::unloadUnusedData(float timeout,
core::list<v3s16> *deleted_blocks) core::list<v3s16> *deleted_blocks)
{ {
core::list<v2s16> sector_deletion_queue; core::list<v2s16> sector_deletion_queue;
u32 deleted_blocks_count = 0;
u32 saved_blocks_count = 0;
core::map<v2s16, MapSector*>::Iterator si = m_sectors.getIterator(); core::map<v2s16, MapSector*>::Iterator si = m_sectors.getIterator();
for(; si.atEnd() == false; si++) for(; si.atEnd() == false; si++)
@ -1453,14 +1440,18 @@ u32 Map::unloadUnusedData(float timeout, bool only_blocks,
i != blocks.end(); i++) i != blocks.end(); i++)
{ {
MapBlock *block = (*i); MapBlock *block = (*i);
if(block->getUsageTimer() > timeout) if(block->getUsageTimer() > timeout)
{ {
// Save if modified // Save if modified
if(block->getModified() != MOD_STATE_CLEAN) if(block->getModified() != MOD_STATE_CLEAN)
{
saveBlock(block); saveBlock(block);
saved_blocks_count++;
}
// Delete from memory // Delete from memory
sector->deleteBlock(block); sector->deleteBlock(block);
deleted_blocks_count++;
} }
else else
{ {
@ -1474,36 +1465,14 @@ u32 Map::unloadUnusedData(float timeout, bool only_blocks,
} }
} }
#if 0 deleteSectors(sector_deletion_queue);
core::map<v2s16, MapSector*>::Iterator i = m_sectors.getIterator();
for(; i.atEnd() == false; i++)
{
MapSector *sector = i.getNode()->getValue();
/*
Delete sector from memory if it hasn't been used in a long time
*/
if(sector->usage_timer > timeout)
{
sector_deletion_queue.push_back(i.getNode()->getKey());
if(deleted_blocks != NULL) dstream<<"Map: Unloaded "<<deleted_blocks_count<<" blocks from memory"
{ <<", of which "<<saved_blocks_count<<" were wr."
// Collect positions of blocks of sector <<std::endl;
MapSector *sector = i.getNode()->getValue();
core::list<MapBlock*> blocks;
sector->getBlocks(blocks);
for(core::list<MapBlock*>::Iterator i = blocks.begin();
i != blocks.end(); i++)
{
deleted_blocks->push_back((*i)->getPos());
}
}
}
}
#endif
deleteSectors(sector_deletion_queue, only_blocks); //return sector_deletion_queue.getSize();
return sector_deletion_queue.getSize(); //return deleted_blocks_count;
} }
void Map::PrintInfo(std::ostream &out) void Map::PrintInfo(std::ostream &out)
@ -2083,6 +2052,8 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
return NULL; return NULL;
} }
bool enable_mapgen_debug_info = g_settings.getBool("enable_mapgen_debug_info");
/*dstream<<"Resulting vmanip:"<<std::endl; /*dstream<<"Resulting vmanip:"<<std::endl;
data->vmanip.print(dstream);*/ data->vmanip.print(dstream);*/
@ -2095,10 +2066,11 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
//TimeTaker timer("finishBlockMake() blitBackAll"); //TimeTaker timer("finishBlockMake() blitBackAll");
data->vmanip->blitBackAll(&changed_blocks); data->vmanip->blitBackAll(&changed_blocks);
} }
#if 1
dstream<<"finishBlockMake: changed_blocks.size()=" if(enable_mapgen_debug_info)
<<changed_blocks.size()<<std::endl; dstream<<"finishBlockMake: changed_blocks.size()="
#endif <<changed_blocks.size()<<std::endl;
/* /*
Copy transforming liquid information Copy transforming liquid information
*/ */
@ -2155,6 +2127,9 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
} }
#endif #endif
updateLighting(lighting_update_blocks, changed_blocks); updateLighting(lighting_update_blocks, changed_blocks);
if(enable_mapgen_debug_info == false)
t.stop(true); // Hide output
} }
/* /*
@ -2269,6 +2244,8 @@ MapBlock * ServerMap::generateBlock(
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<")" <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
<<std::endl;*/ <<std::endl;*/
bool enable_mapgen_debug_info = g_settings.getBool("enable_mapgen_debug_info");
TimeTaker timer("generateBlock"); TimeTaker timer("generateBlock");
//MapBlock *block = original_dummy; //MapBlock *block = original_dummy;
@ -2297,6 +2274,9 @@ MapBlock * ServerMap::generateBlock(
{ {
TimeTaker t("mapgen::make_block()"); TimeTaker t("mapgen::make_block()");
mapgen::make_block(&data); mapgen::make_block(&data);
if(enable_mapgen_debug_info == false)
t.stop(true); // Hide output
} }
/* /*
@ -2355,6 +2335,9 @@ MapBlock * ServerMap::generateBlock(
} }
#endif #endif
if(enable_mapgen_debug_info == false)
timer.stop(true); // Hide output
return block; return block;
} }

@ -230,13 +230,18 @@ public:
Updates usage timers Updates usage timers
*/ */
void timerUpdate(float dtime); void timerUpdate(float dtime);
// Deletes sectors and their blocks from memory
// Takes cache into account // Takes cache into account
// sector mutex should be locked when calling // If deleted sector is in sector cache, clears cache
void deleteSectors(core::list<v2s16> &list, bool only_blocks); void deleteSectors(core::list<v2s16> &list);
// Returns count of deleted sectors /*
u32 unloadUnusedData(float timeout, bool only_blocks=false, Unload unused data
= flush changed to disk and delete from memory, if usage timer of
block is more than timeout
*/
void unloadUnusedData(float timeout,
core::list<v3s16> *deleted_blocks=NULL); core::list<v3s16> *deleted_blocks=NULL);
// For debug printing // For debug printing

@ -38,7 +38,7 @@ MapBlock::MapBlock(Map *parent, v3s16 pos, bool dummy):
m_generated(false), m_generated(false),
m_objects(this), m_objects(this),
m_timestamp(BLOCK_TIMESTAMP_UNDEFINED), m_timestamp(BLOCK_TIMESTAMP_UNDEFINED),
m_usage_timer(BLOCK_TIMESTAMP_UNDEFINED) m_usage_timer(0)
{ {
data = NULL; data = NULL;
if(dummy == false) if(dummy == false)

@ -1389,7 +1389,7 @@ void make_block(BlockMakeData *data)
/* /*
Create a block-specific seed Create a block-specific seed
*/ */
u32 blockseed = (data->seed%0x100000000) + full_node_min.Z*38134234 u32 blockseed = (u32)(data->seed%0x100000000) + full_node_min.Z*38134234
+ full_node_min.Y*42123 + full_node_min.X*23; + full_node_min.Y*42123 + full_node_min.X*23;
/* /*

@ -1831,17 +1831,21 @@ void Server::AsyncRunStep()
JMutexAutoLock lock(m_env_mutex); JMutexAutoLock lock(m_env_mutex);
if(((ServerMap*)(&m_env.getMap()))->isSavingEnabled() == true) if(((ServerMap*)(&m_env.getMap()))->isSavingEnabled() == true)
{ {
// Unload unused data (delete from memory)
m_env.getMap().unloadUnusedData(
g_settings.getFloat("server_unload_unused_sectors_timeout"));
/*u32 deleted_count = m_env.getMap().unloadUnusedData(
g_settings.getFloat("server_unload_unused_sectors_timeout"));
*/
// Save only changed parts // Save only changed parts
m_env.getMap().save(true); m_env.getMap().save(true);
// Delete unused sectors /*if(deleted_count > 0)
u32 deleted_count = m_env.getMap().unloadUnusedData(
g_settings.getFloat("server_unload_unused_sectors_timeout"));
if(deleted_count > 0)
{ {
dout_server<<"Server: Unloaded "<<deleted_count dout_server<<"Server: Unloaded "<<deleted_count
<<" sectors from memory"<<std::endl; <<" blocks from memory"<<std::endl;
} }*/
// Save players // Save players
m_env.serializePlayers(m_mapsavedir); m_env.serializePlayers(m_mapsavedir);