Skip to content
Permalink
Browse files

Record MapBlock modification reasons as flags instead of strings

This improves performance of MapBlock::raiseModified by a factor of 6.
Also, clean up mapblock.h a bit and inline small functions.
  • Loading branch information
kwolekr committed May 18, 2015
1 parent 4c9a8a9 commit 46684beec185d13f89c4a91aaa5dd2148ebb0273
Showing with 286 additions and 233 deletions.
  1. +11 −14 src/environment.cpp
  2. +3 −3 src/map.cpp
  3. +46 −2 src/mapblock.cpp
  4. +222 −211 src/mapblock.h
  5. +1 −1 src/rollback_interface.cpp
  6. +3 −2 src/script/lua_api/l_nodemeta.cpp
@@ -873,7 +873,7 @@ void ServerEnvironment::clearAllObjects()
if(block){
block->m_static_objects.remove(id);
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"clearAllObjects");
MOD_REASON_CLEAR_ALL_OBJECTS);
obj->m_static_exists = false;
}
}
@@ -952,7 +952,7 @@ void ServerEnvironment::clearAllObjects()
block->m_static_objects.m_stored.clear();
block->m_static_objects.m_active.clear();
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"clearAllObjects");
MOD_REASON_CLEAR_ALL_OBJECTS);
num_objs_cleared += num_stored + num_active;
num_blocks_cleared++;
}
@@ -1139,7 +1139,7 @@ void ServerEnvironment::step(float dtime)
// set block to be saved when it is unloaded
if(block->getTimestamp() > block->getDiskTimestamp() + 60)
block->raiseModified(MOD_STATE_WRITE_AT_UNLOAD,
"Timestamp older than 60s (step)");
MOD_REASON_BLOCK_EXPIRED);

// Run node timers
std::map<v3s16, NodeTimer> elapsed_timers =
@@ -1530,7 +1530,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,

if(set_changed)
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"addActiveObjectRaw");
MOD_REASON_ADD_ACTIVE_OBJECT_RAW);
} else {
v3s16 p = floatToInt(objectpos, BS);
errorstream<<"ServerEnvironment::addActiveObjectRaw(): "
@@ -1579,7 +1579,7 @@ void ServerEnvironment::removeRemovedObjects()
if (block) {
block->m_static_objects.remove(id);
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"removeRemovedObjects/remove");
MOD_REASON_REMOVE_OBJECTS_REMOVE);
obj->m_static_exists = false;
} else {
infostream<<"Failed to emerge block from which an object to "
@@ -1604,7 +1604,7 @@ void ServerEnvironment::removeRemovedObjects()
block->m_static_objects.m_stored.push_back(i->second);
block->m_static_objects.m_active.erase(id);
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"removeRemovedObjects/deactivate");
MOD_REASON_REMOVE_OBJECTS_DEACTIVATE);
}
} else {
infostream<<"Failed to emerge block from which an object to "
@@ -1690,8 +1690,7 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
// Clear stored list
block->m_static_objects.m_stored.clear();
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"stored list cleared in activateObjects due to "
"large amount of objects");
MOD_REASON_TOO_MANY_OBJECTS);
return;
}

@@ -1812,7 +1811,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
block->m_static_objects.insert(id, s_obj);
obj->m_static_block = blockpos_o;
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"deactivateFarObjects: Static data moved in");
MOD_REASON_STATIC_DATA_ADDED);

// Delete from block where object was located
block = m_map->emergeBlock(old_static_block, false);
@@ -1825,7 +1824,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
}
block->m_static_objects.remove(id);
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"deactivateFarObjects: Static data moved out");
MOD_REASON_STATIC_DATA_REMOVED);
continue;
}

@@ -1890,8 +1889,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
// Only mark block as modified if data changed considerably
if(shall_be_written)
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"deactivateFarObjects: Static data "
"changed considerably");
MOD_REASON_STATIC_DATA_CHANGED);
}
}

@@ -1937,8 +1935,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
// Only mark block as modified if data changed considerably
if(shall_be_written)
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"deactivateFarObjects: Static data "
"changed considerably");
MOD_REASON_STATIC_DATA_CHANGED);

obj->m_static_exists = true;
obj->m_static_block = block->getPos();
@@ -1436,7 +1436,7 @@ void Map::timerUpdate(float dtime, float unload_timeout,

// Save if modified
if (block->getModified() != MOD_STATE_CLEAN && save_before_unloading) {
modprofiler.add(block->getModifiedReason(), 1);
modprofiler.add(block->getModifiedReasonString(), 1);
if (!saveBlock(block))
continue;
saved_blocks_count++;
@@ -2412,7 +2412,7 @@ void ServerMap::finishBlockMake(BlockMakeData *data,
Set block as modified
*/
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"finishBlockMake expireDayNightDiff");
MOD_REASON_EXPIRE_DAYNIGHTDIFF);
}

/*
@@ -2981,7 +2981,7 @@ void ServerMap::save(ModifiedState save_level)
save_started = true;
}

modprofiler.add(block->getModifiedReason(), 1);
modprofiler.add(block->getModifiedReasonString(), 1);

saveBlock(block);
block_count++;
@@ -38,6 +38,30 @@ with this program; if not, write to the Free Software Foundation, Inc.,

#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"

static const char *modified_reason_strings[] = {
"initial",
"reallocate",
"setIsUnderground",
"setLightingExpired",
"setGenerated",
"setNode",
"setNodeNoCheck",
"setTimestamp",
"NodeMetaRef::reportMetadataChange",
"clearAllObjects",
"Timestamp expired (step)",
"addActiveObjectRaw",
"removeRemovedObjects/remove",
"removeRemovedObjects/deactivate",
"Stored list cleared in activateObjects due to overflow",
"deactivateFarObjects: Static data moved in",
"deactivateFarObjects: Static data moved out",
"deactivateFarObjects: Static data changed considerably",
"finishBlockMake: expireDayNightDiff"
"unknown",
};


/*
MapBlock
*/
@@ -47,8 +71,7 @@ MapBlock::MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy):
m_pos(pos),
m_gamedef(gamedef),
m_modified(MOD_STATE_WRITE_NEEDED),
m_modified_reason("initial"),
m_modified_reason_too_long(false),
m_modified_reason(MOD_REASON_INITIAL),
is_underground(false),
m_lighting_expired(true),
m_day_night_differs(false),
@@ -112,6 +135,27 @@ MapNode MapBlock::getNodeParent(v3s16 p, bool *is_valid_position)
return data[p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X];
}

std::string MapBlock::getModifiedReasonString()
{
std::string reason;

const u32 ubound = MYMIN(sizeof(m_modified_reason) * CHAR_BIT,
ARRLEN(modified_reason_strings));

for (u32 i = 0; i != ubound; i++) {
if ((m_modified_reason & (1 << i)) == 0)
continue;

reason += modified_reason_strings[i];
reason += ", ";
}

if (reason.length() > 2)
reason.resize(reason.length() - 2);

return reason;
}

/*
Propagates sunlight down through the block.
Doesn't modify nodes that are not affected by sunlight.

0 comments on commit 46684be

Please sign in to comment.
You can’t perform that action at this time.