summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mapblock.cpp24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index 910e91316..f52a5ee3f 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -494,22 +494,44 @@ static void correctBlockNodeIds(const NameIdMapping *nimap, MapNode *nodes,
// correct ids.
std::unordered_set<content_t> unnamed_contents;
std::unordered_set<std::string> unallocatable_contents;
+
+ bool previous_was_found = false;
+ content_t previous_local_id = CONTENT_IGNORE;
+ content_t previous_global_id = CONTENT_IGNORE;
+
for (u32 i = 0; i < MapBlock::nodecount; i++) {
content_t local_id = nodes[i].getContent();
+ // If previous node local_id was found and same than before, don't lookup maps
+ // apply directly previous resolved id
+ // This permits to massively improve loading performance when nodes are similar
+ // example: default:air, default:stone are massively present
+ if (previous_was_found && local_id == previous_local_id) {
+ nodes[i].setContent(previous_global_id);
+ continue;
+ }
+
std::string name;
if (!nimap->getName(local_id, name)) {
unnamed_contents.insert(local_id);
+ previous_was_found = false;
continue;
}
+
content_t global_id;
if (!nodedef->getId(name, global_id)) {
global_id = gamedef->allocateUnknownNodeId(name);
- if(global_id == CONTENT_IGNORE){
+ if (global_id == CONTENT_IGNORE) {
unallocatable_contents.insert(name);
+ previous_was_found = false;
continue;
}
}
nodes[i].setContent(global_id);
+
+ // Save previous node local_id & global_id result
+ previous_local_id = local_id;
+ previous_global_id = global_id;
+ previous_was_found = true;
}
for (const content_t c: unnamed_contents) {