Cache some hotpath inverses regarding context handling

This commit is contained in:
Thomas Krijnen
2026-04-07 16:13:01 +02:00
parent a19d398c78
commit a425bb6da0
2 changed files with 52 additions and 11 deletions
+43 -10
View File
@@ -1283,26 +1283,59 @@ void mapping::addRepresentationsFromDefaultContexts(std::vector<IfcSchema::IfcRe
} }
} }
express::Base mapping::representation_of(const express::Base& product) { void mapping::ensureRepresentationContextCache_() {
// @todo correct, but very inefficient const auto has_context_ids = settings_.get<settings::ContextIds>().has();
std::vector<IfcSchema::IfcRepresentation> representations; const auto dimensionality = settings_.get<settings::OutputDimensionality>().get();
std::vector<IfcSchema::IfcRepresentation> of_product; const auto context_ids = has_context_ids ? settings_.get<settings::ContextIds>().get() : std::set<int>{};
std::vector<IfcSchema::IfcRepresentation> intersection;
std::vector<IfcSchema::IfcRepresentation> intersection_no_box;
if (!settings_.get<settings::ContextIds>().has()) { std::lock_guard<std::mutex> guard(representation_context_cache_guard_);
if (representation_context_cache_valid_ &&
representation_context_cache_has_context_ids_ == has_context_ids &&
representation_context_cache_dimensionality_ == dimensionality &&
representation_context_cache_ids_ == context_ids) {
return;
}
std::vector<IfcSchema::IfcRepresentation> representations;
if (!has_context_ids) {
addRepresentationsFromDefaultContexts(representations); addRepresentationsFromDefaultContexts(representations);
} else { } else {
addRepresentationsFromContextIds(representations); addRepresentationsFromContextIds(representations);
} }
std::unordered_set<uint32_t> representation_ids;
representation_ids.reserve(representations.size());
for (auto& representation : representations) {
if (representation) {
representation_ids.insert((uint32_t)representation.id());
}
}
representation_context_cache_ = std::move(representation_ids);
representation_context_cache_ids_ = std::move(context_ids);
representation_context_cache_dimensionality_ = dimensionality;
representation_context_cache_has_context_ids_ = has_context_ids;
representation_context_cache_valid_ = true;
}
express::Base mapping::representation_of(const express::Base& product) {
std::vector<IfcSchema::IfcRepresentation> of_product;
std::vector<IfcSchema::IfcRepresentation> intersection;
std::vector<IfcSchema::IfcRepresentation> intersection_no_box;
ensureRepresentationContextCache_();
if (product.as<IfcSchema::IfcProduct>().Representation()) { if (product.as<IfcSchema::IfcProduct>().Representation()) {
of_product = product.as<IfcSchema::IfcProduct>().Representation().Representations(); of_product = product.as<IfcSchema::IfcProduct>().Representation().Representations();
} }
for (auto& r : of_product) { {
if (std::find(representations.begin(), representations.end(), r) != representations.end()) { std::lock_guard<std::mutex> guard(representation_context_cache_guard_);
intersection.push_back(r); for (auto& r : of_product) {
if (representation_context_cache_.find((uint32_t)r.id()) != representation_context_cache_.end()) {
intersection.push_back(r);
}
} }
} }
+9 -1
View File
@@ -7,6 +7,7 @@
#include "../../ifcparse/logger.h" #include "../../ifcparse/logger.h"
#include <mutex> #include <mutex>
#include <unordered_set>
#define INCLUDE_SCHEMA(x) STRINGIFY(../../ifcparse/schemas/x.h) #define INCLUDE_SCHEMA(x) STRINGIFY(../../ifcparse/schemas/x.h)
#include INCLUDE_SCHEMA(IfcSchema) #include INCLUDE_SCHEMA(IfcSchema)
@@ -36,11 +37,18 @@ namespace geometry {
void initialize_units_(); void initialize_units_();
void addRepresentationsFromContextIds(std::vector<IfcSchema::IfcRepresentation>&); void addRepresentationsFromContextIds(std::vector<IfcSchema::IfcRepresentation>&);
void addRepresentationsFromDefaultContexts(std::vector<IfcSchema::IfcRepresentation>&); void addRepresentationsFromDefaultContexts(std::vector<IfcSchema::IfcRepresentation>&);
void ensureRepresentationContextCache_();
// Set of instances to mark failures that are intended, such as representations not // Set of instances to mark failures that are intended, such as representations not
// resulting in any items due to dimensionality filters. // resulting in any items due to dimensionality filters.
std::set<express::Base> failed_on_purpose_; std::set<express::Base> failed_on_purpose_;
std::set<IfcSchema::IfcRepresentationMap> not_reusable_maps_; std::set<IfcSchema::IfcRepresentationMap> not_reusable_maps_;
std::unordered_set<uint32_t> representation_context_cache_;
std::set<int> representation_context_cache_ids_;
settings::OutputDimensionalityTypes representation_context_cache_dimensionality_ = settings::SURFACES_AND_SOLIDS;
bool representation_context_cache_has_context_ids_ = false;
bool representation_context_cache_valid_ = false;
std::mutex representation_context_cache_guard_;
template <typename T> template <typename T>
void process_mapping(bool& matched, taxonomy::ptr& item, const express::Base& inst) { void process_mapping(bool& matched, taxonomy::ptr& item, const express::Base& inst) {
@@ -152,4 +160,4 @@ namespace geometry {
} }
#endif #endif