minetest-0001: mg_ore.cpp c_wherein vector CONTAINS in voxel inner loop O(V*W) HIGH 3.3x minetest-0002: mg_decoration.cpp c_place_on/c_spawnby vector CONTAINS O(S*P) MEDIUM 1.8x minetest-0003: l_env.cpp find_node_near/find_nodes_in_area filter CONTAINS O(V*F) MEDIUM 1.6x minetest-0004: nodedef.cpp nodeboxConnects sorted vector linear scan O(N) MEDIUM 2.1x minetest-0005: blockmodifier.cpp ABM neighbor check sorted vector O(N) LOW-MEDIUM 1.5x MOAD-0002: g_settings global singleton (architectural, not patchable) MOAD-0003: thread_local log streams (properly scoped, not leaked context) MOAD-0004: CLEAN (no credential logging found) MOAD-0005: CLEAN (no unsynchronized cache patterns found)
56 lines
2.2 KiB
Diff
56 lines
2.2 KiB
Diff
# UNDF: UNDF-2026-000000940
|
|
--- a/src/script/lua_api/l_env.cpp
|
|
+++ b/src/script/lua_api/l_env.cpp
|
|
@@ -809,11 +809,12 @@ template <typename F>
|
|
int ModApiEnvBase::findNodeNear(lua_State *L, v3s16 pos, int radius,
|
|
- const std::vector<content_t> &filter, int start_radius, F &&getNode)
|
|
+ const std::vector<content_t> &filter_vec, int start_radius, F &&getNode)
|
|
{
|
|
+ std::unordered_set<content_t> filter(filter_vec.begin(), filter_vec.end());
|
|
for (int d = start_radius; d <= radius; d++) {
|
|
const std::vector<v3s16> &list = FacePositionCache::getFacePositions(d);
|
|
for (const v3s16 &i : list) {
|
|
v3s16 p = pos + i;
|
|
content_t c = getNode(p).getContent();
|
|
- if (CONTAINS(filter, c)) {
|
|
+ if (filter.count(c) > 0) {
|
|
push_v3s16(L, p);
|
|
return 1;
|
|
@@ -884,7 +885,8 @@ int ModApiEnvBase::findNodesInArea(lua_State *L, const NodeDefManager *ndef,
|
|
|
|
iterate([&](v3s16 p, MapNode n) -> bool {
|
|
content_t c = n.getContent();
|
|
-
|
|
- auto it = std::find(filter.begin(), filter.end(), c);
|
|
- if (it != filter.end()) {
|
|
+ // Build a hash map for O(1) lookup; also need index, so use
|
|
+ // unordered_map<content_t, u32> built once before the iterate.
|
|
+ auto it = filter_map.find(c);
|
|
+ if (it != filter_map.end()) {
|
|
// Calculate index of the table and append the position
|
|
- u32 filt_index = it - filter.begin();
|
|
+ u32 filt_index = it->second;
|
|
|
|
// Similarly for the non-grouped branch:
|
|
@@ -918,8 +920,8 @@ int ModApiEnvBase::findNodesInArea(...)
|
|
iterate([&](v3s16 p, MapNode n) -> bool {
|
|
content_t c = n.getContent();
|
|
-
|
|
- auto it = std::find(filter.begin(), filter.end(), c);
|
|
- if (it != filter.end()) {
|
|
+ auto it = filter_map.find(c);
|
|
+ if (it != filter_map.end()) {
|
|
push_v3s16(L, p);
|
|
lua_rawseti(L, -2, ++i);
|
|
- u32 filt_index = it - filter.begin();
|
|
+ u32 filt_index = it->second;
|
|
|
|
// findNodesInAreaUnderAir: same pattern
|
|
@@ -989,7 +991,7 @@ int ModApiEnvBase::findNodesInAreaUnderAir(...)
|
|
+ std::unordered_set<content_t> filter_set(filter.begin(), filter.end());
|
|
for (p.X = minp.X; p.X <= maxp.X; p.X++)
|
|
for (p.Z = minp.Z; p.Z <= maxp.Z; p.Z++) {
|
|
...
|
|
if (c != CONTENT_AIR && csurf == CONTENT_AIR &&
|
|
- CONTAINS(filter, c)) {
|
|
+ filter_set.count(c) > 0) {
|