java-topology/defects/solvespace-0002/patch/solvespace-0002-vrml-export-colour-hashmap.patch
russell@unturf.com 5575f6cd9c jitsi-meet+solvespace: 5-MOAD scan; 3 new CWE-407 defects
jitsi-meet-0003: av-moderation pendingAudio/Video/Desktop Array.find()
dedup O(P^2) in large moderated meetings — 249.5x op-count at P=500,
138.5x measured at P=2000. Fix: Map<id, participant> for O(1) dedup.

jitsi-meet-0004: visitors middleware delta Array.findIndex() per update
O(U*V) in large broadcast events — 15x at V=5000 U=1000. Fix: Map-based
apply-delta O(1) per join/leave.

solvespace-0002: VRML export colours_present std::vector + find_if
O(T*C) per triangle — 250x op-count at T=50k C=500. Fix: unordered_map
keyed by ToPackedInt() RGBA uint32.

MOAD-0002/0003/0004/0005: CLEAN for both targets.
All 13 unit tests PASS.
2026-03-31 22:42:46 -04:00

39 lines
2.1 KiB
Diff

# UNDF: (to be assigned)
--- a/src/export.cpp
+++ b/src/export.cpp
@@ -1220,24 +1220,23 @@ void ExportWrlMeshes(FILE *f, const char *basename, SMesh *sm, RgbaColor clr) {
fputs(" ]\n"
" color Color { color [\n", f);
// Output triangle colors.
std::vector<int> triangle_colour_ids;
- std::vector<RgbaColor> colours_present;
+ // Use unordered_map<packed-RGBA, index> for O(1) colour dedup
+ // instead of std::vector + std::find_if which is O(T*C).
+ // RgbaColor::ToPackedInt() produces a unique uint32_t per RGBA tuple.
+ std::unordered_map<uint32_t, int> colour_to_index;
+ int next_colour_index = 0;
for(const auto & sp : op.second) {
for(const auto & tr : sp) {
- const auto colour_itr = std::find_if(colours_present.begin(), colours_present.end(),
- [&](const RgbaColor & c) {
- return c.Equals(tr.meta.color);
- });
- if(colour_itr == colours_present.end()) {
+ uint32_t key = tr.meta.color.ToPackedInt();
+ auto it = colour_to_index.find(key);
+ if(it == colour_to_index.end()) {
fprintf(f, " %.10f %.10f %.10f,\n",
tr.meta.color.redF(),
tr.meta.color.greenF(),
tr.meta.color.blueF());
- triangle_colour_ids.push_back(colours_present.size());
- colours_present.insert(colours_present.end(), tr.meta.color);
+ colour_to_index[key] = next_colour_index;
+ triangle_colour_ids.push_back(next_colour_index);
+ ++next_colour_index;
} else {
- triangle_colour_ids.push_back(colour_itr - colours_present.begin());
+ triangle_colour_ids.push_back(it->second);
}
}
}