diff options
author | sfan5 <sfan5@live.de> | 2022-05-09 20:00:22 +0200 |
---|---|---|
committer | sfan5 <sfan5@live.de> | 2022-05-26 15:49:12 +0200 |
commit | 9a01581cdd3cb54750e9fe4a065aa435262d5225 (patch) | |
tree | 9472fccfddc31a56b38bbb2af60dab3714420cbe | |
parent | 5d26ac00883eed2f522e6e0fa3adcd7081814c9b (diff) | |
download | minetest-9a01581cdd3cb54750e9fe4a065aa435262d5225.tar.gz minetest-9a01581cdd3cb54750e9fe4a065aa435262d5225.tar.bz2 minetest-9a01581cdd3cb54750e9fe4a065aa435262d5225.zip |
Get rid of global buffer that would ruin concurrent MapBlock serialization
-rw-r--r-- | src/mapblock.cpp | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/src/mapblock.cpp b/src/mapblock.cpp index e3a6caa19..2bbc0ebbf 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -221,33 +221,36 @@ void MapBlock::expireDayNightDiff() /* Serialization */ + // List relevant id-name pairs for ids in the block using nodedef -// Renumbers the content IDs (starting at 0 and incrementing -// use static memory requires about 65535 * sizeof(int) ram in order to be -// sure we can handle all content ids. But it's absolutely worth it as it's -// a speedup of 4 for one of the major time consuming functions on storing -// mapblocks. -static content_t getBlockNodeIdMapping_mapping[USHRT_MAX + 1]; +// Renumbers the content IDs (starting at 0 and incrementing) static void getBlockNodeIdMapping(NameIdMapping *nimap, MapNode *nodes, const NodeDefManager *nodedef) { - memset(getBlockNodeIdMapping_mapping, 0xFF, (USHRT_MAX + 1) * sizeof(content_t)); - - std::set<content_t> unknown_contents; + // The static memory requires about 65535 * sizeof(int) RAM in order to be + // sure we can handle all content ids. But it's absolutely worth it as it's + // a speedup of 4 for one of the major time consuming functions on storing + // mapblocks. + thread_local std::unique_ptr<content_t[]> mapping; + static_assert(sizeof(content_t) == 2, "content_t must be 16-bit"); + if (!mapping) + mapping = std::make_unique<content_t[]>(USHRT_MAX + 1); + + memset(mapping.get(), 0xFF, (USHRT_MAX + 1) * sizeof(content_t)); + + std::unordered_set<content_t> unknown_contents; content_t id_counter = 0; for (u32 i = 0; i < MapBlock::nodecount; i++) { content_t global_id = nodes[i].getContent(); content_t id = CONTENT_IGNORE; // Try to find an existing mapping - if (getBlockNodeIdMapping_mapping[global_id] != 0xFFFF) { - id = getBlockNodeIdMapping_mapping[global_id]; - } - else - { + if (mapping[global_id] != 0xFFFF) { + id = mapping[global_id]; + } else { // We have to assign a new mapping id = id_counter++; - getBlockNodeIdMapping_mapping[global_id] = id; + mapping[global_id] = id; const ContentFeatures &f = nodedef->get(global_id); const std::string &name = f.name; @@ -265,6 +268,7 @@ static void getBlockNodeIdMapping(NameIdMapping *nimap, MapNode *nodes, << "Name for node id " << unknown_content << " not known" << std::endl; } } + // Correct ids in the block to match nodedef based on names. // Unknown ones are added to nodedef. // Will not update itself to match id-name pairs in nodedef. |