mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 11:53:44 +00:00
Get rid of parse context pool
This commit is contained in:
@@ -21,9 +21,9 @@ ifcopenshell::parse_context::~parse_context() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ifcopenshell::parse_context& ifcopenshell::parse_context::push() {
|
ifcopenshell::parse_context& ifcopenshell::parse_context::push() {
|
||||||
auto child = pool_->make();
|
auto* pc = new parse_context;
|
||||||
tokens_.emplace_back(child);
|
tokens_.push_back(pc);
|
||||||
return *child;
|
return *pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ifcopenshell::parse_context::push(token t) {
|
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>) {
|
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, ifcopenshell::token>) {
|
||||||
// @todo get aggregate of enumeration
|
// @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);
|
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
|
// nested list
|
||||||
if constexpr (Depth < 3) {
|
if constexpr (Depth < 3) {
|
||||||
construct_<Depth + 1>(instance_id, attribute_id, *v, nullptr, append_to_aggregate_storage);
|
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);
|
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;
|
const auto *pt = param_type;
|
||||||
if (pt) {
|
if (pt) {
|
||||||
while (pt->as_named_type() && pt->as_named_type()->declared_type()->as_type_declaration()) {
|
while (pt->as_named_type() && pt->as_named_type()->declared_type()->as_type_declaration()) {
|
||||||
|
|||||||
@@ -602,7 +602,7 @@ void ifcopenshell::impl::in_memory_file_storage::load(ifcopenshell::spf_lexer<Re
|
|||||||
if (next.is_keyword()) {
|
if (next.is_keyword()) {
|
||||||
try {
|
try {
|
||||||
const auto* decl = (schema ? schema : file->schema())->declaration_by_name(next.as_string());
|
const auto* decl = (schema ? schema : file->schema())->declaration_by_name(next.as_string());
|
||||||
parse_context ps(&context_pool_);
|
parse_context ps;
|
||||||
tokens->next();
|
tokens->next();
|
||||||
// The only case we know where a defined type contains entity
|
// The only case we know where a defined type contains entity
|
||||||
// instance references is IfcPropertySetDefinitionSet. For
|
// instance references is IfcPropertySetDefinitionSet. For
|
||||||
@@ -1387,11 +1387,10 @@ std::shared_ptr<instance_data> read_header_entity(
|
|||||||
spf_lexer<Reader>& lexer,
|
spf_lexer<Reader>& lexer,
|
||||||
ifcopenshell::unresolved_references& references_to_resolve,
|
ifcopenshell::unresolved_references& references_to_resolve,
|
||||||
const ifcopenshell::entity& decl) {
|
const ifcopenshell::entity& decl) {
|
||||||
parse_context pc(&storage.context_pool_);
|
parse_context pc;
|
||||||
lexer.next();
|
lexer.next();
|
||||||
storage.load(&lexer, std::nullopt, nullptr, pc, -1);
|
storage.load(&lexer, std::nullopt, nullptr, pc, -1);
|
||||||
auto result = pc.construct(file, std::nullopt, references_to_resolve, &decl, decl.attribute_count(), -1);
|
auto result = pc.construct(file, std::nullopt, references_to_resolve, &decl, decl.attribute_count(), -1);
|
||||||
storage.context_pool_.reset();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1436,7 +1435,6 @@ bool try_parse_header(
|
|||||||
parse_header(header, storage, lexer, references_to_resolve);
|
parse_header(header, storage, lexer, references_to_resolve);
|
||||||
return true;
|
return true;
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
storage.context_pool_.reset();
|
|
||||||
logger::error(e);
|
logger::error(e);
|
||||||
return false;
|
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();
|
lexer_->next();
|
||||||
try {
|
try {
|
||||||
storage_.load(lexer_.get(), current_id, entity_type->as_entity(), ps, -1);
|
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);
|
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(
|
return_value.emplace(
|
||||||
(size_t)current_id,
|
(size_t)current_id,
|
||||||
|
|||||||
+2
-59
@@ -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 {
|
struct IFC_PARSE_API parse_context {
|
||||||
std::vector<
|
std::vector<
|
||||||
std::variant<
|
std::variant<
|
||||||
express::Base,
|
express::Base,
|
||||||
token,
|
token,
|
||||||
parse_context_handle
|
parse_context*
|
||||||
>> tokens_;
|
>> tokens_;
|
||||||
|
|
||||||
void reset() {
|
parse_context() {}
|
||||||
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;
|
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);
|
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 {
|
namespace impl {
|
||||||
struct IFC_PARSE_API in_memory_file_storage {
|
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>> read_simple_type_instances;
|
||||||
std::vector<std::shared_ptr<instance_data>> steal_instances() {
|
std::vector<std::shared_ptr<instance_data>> steal_instances() {
|
||||||
|
|||||||
Reference in New Issue
Block a user