Get rid of parse context pool

This commit is contained in:
Thomas Krijnen
2026-04-22 12:03:58 +02:00
parent 89c66f62bf
commit 9b13dc8dd6
3 changed files with 10 additions and 70 deletions
+5 -5
View File
@@ -21,9 +21,9 @@ ifcopenshell::parse_context::~parse_context() {
}
ifcopenshell::parse_context& ifcopenshell::parse_context::push() {
auto child = pool_->make();
tokens_.emplace_back(child);
return *child;
auto* pc = new parse_context;
tokens_.push_back(pc);
return *pc;
}
void ifcopenshell::parse_context::push(token t) {
@@ -220,7 +220,7 @@ namespace {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, ifcopenshell::token>) {
// @todo get aggregate of enumeration
dispatch_token(instance_id, attribute_id, v, aggr && aggr->type_of_element()->as_named_type() ? aggr->type_of_element()->as_named_type()->declared_type() : nullptr, append_to_aggregate_storage);
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, ifcopenshell::parse_context_handle>) {
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, ifcopenshell::parse_context*>) {
// nested list
if constexpr (Depth < 3) {
construct_<Depth + 1>(instance_id, attribute_id, *v, nullptr, append_to_aggregate_storage);
@@ -307,7 +307,7 @@ std::shared_ptr<instance_data> ifcopenshell::parse_context::construct(ifcopenshe
storage.set(index, v);
}
});
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, ifcopenshell::parse_context_handle>) {
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, ifcopenshell::parse_context*>) {
const auto *pt = param_type;
if (pt) {
while (pt->as_named_type() && pt->as_named_type()->declared_type()->as_type_declaration()) {
+3 -6
View File
@@ -602,7 +602,7 @@ void ifcopenshell::impl::in_memory_file_storage::load(ifcopenshell::spf_lexer<Re
if (next.is_keyword()) {
try {
const auto* decl = (schema ? schema : file->schema())->declaration_by_name(next.as_string());
parse_context ps(&context_pool_);
parse_context ps;
tokens->next();
// The only case we know where a defined type contains entity
// instance references is IfcPropertySetDefinitionSet. For
@@ -1387,11 +1387,10 @@ std::shared_ptr<instance_data> read_header_entity(
spf_lexer<Reader>& lexer,
ifcopenshell::unresolved_references& references_to_resolve,
const ifcopenshell::entity& decl) {
parse_context pc(&storage.context_pool_);
parse_context pc;
lexer.next();
storage.load(&lexer, std::nullopt, nullptr, pc, -1);
auto result = pc.construct(file, std::nullopt, references_to_resolve, &decl, decl.attribute_count(), -1);
storage.context_pool_.reset();
return result;
}
@@ -1436,7 +1435,6 @@ bool try_parse_header(
parse_header(header, storage, lexer, references_to_resolve);
return true;
} catch (const std::exception& e) {
storage.context_pool_.reset();
logger::error(e);
return false;
}
@@ -1697,7 +1695,7 @@ std::optional<std::tuple<size_t, const ifcopenshell::declaration*, std::shared_p
}
}
parse_context ps(&storage_.context_pool_);
parse_context ps;
lexer_->next();
try {
storage_.load(lexer_.get(), current_id, entity_type->as_entity(), ps, -1);
@@ -1714,7 +1712,6 @@ std::optional<std::tuple<size_t, const ifcopenshell::declaration*, std::shared_p
}
auto data = ps.construct(owner_, current_id, references_to_resolve_, entity_type, std::nullopt, -1, coerce_attribute_count);
storage_.context_pool_.reset();
return_value.emplace(
(size_t)current_id,
+2 -59
View File
@@ -203,36 +203,15 @@ namespace ifcopenshell {
}
};
struct parse_context;
struct parse_context_pool;
struct IFC_PARSE_API parse_context_handle {
parse_context_pool* pool = nullptr;
uint32_t index = 0;
parse_context& get() const;
parse_context* operator->() const;
parse_context& operator*() const;
explicit operator bool() const { return pool != nullptr; }
};
struct IFC_PARSE_API parse_context {
std::vector<
std::variant<
express::Base,
token,
parse_context_handle
parse_context*
>> tokens_;
void reset() {
tokens_.clear();
}
parse_context_pool* pool_;
parse_context(parse_context_pool* pool) : pool_(pool) {
tokens_.reserve(16);
};
parse_context() {}
~parse_context();
parse_context(const parse_context& other) = delete;
@@ -250,44 +229,8 @@ namespace ifcopenshell {
std::shared_ptr<instance_data> construct(ifcopenshell::file* owner_file, std::optional<size_t> instance_name, unresolved_references& references_to_resolve, const ifcopenshell::declaration* declaration, std::optional<size_t> expected_size, int resolve_reference_index, bool coerce_attribute_count = true);
};
struct IFC_PARSE_API parse_context_pool {
// parse_context::push() stores child handles on the current context after
// requesting a new pool slot. The pool therefore needs stable addresses
// for existing contexts while it grows.
std::deque<parse_context> nodes_;
uint32_t used_ = 0;
void reset() { used_ = 0; }
parse_context_handle make() {
if (used_ == nodes_.size()) {
nodes_.emplace_back(this);
}
auto idx = used_++;
nodes_[idx].reset();
return {this, idx};
}
parse_context& get(uint32_t index) {
return nodes_[index];
}
};
inline parse_context& parse_context_handle::get() const {
return pool->get(index);
}
inline parse_context* parse_context_handle::operator->() const {
return &pool->get(index);
}
inline parse_context& parse_context_handle::operator*() const {
return pool->get(index);
}
namespace impl {
struct IFC_PARSE_API in_memory_file_storage {
ifcopenshell::parse_context_pool context_pool_;
std::vector<std::shared_ptr<instance_data>> read_simple_type_instances;
std::vector<std::shared_ptr<instance_data>> steal_instances() {