mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 19:07:57 +00:00
Fix examples mostly
This commit is contained in:
@@ -35,15 +35,15 @@ namespace {
|
||||
{
|
||||
auto s = sizeof(size_t);
|
||||
val.resize(s + 2);
|
||||
val[0] = TypeEncoder::encode_type<IfcUtil::IfcBaseClass*>();
|
||||
val[0] = TypeEncoder::encode_type<express::Base>();
|
||||
// 1 = entity - stored by id (entity name)
|
||||
// 2 = type - stored by identity (internal counter in class)
|
||||
val[1] = t.index() == 0 ? 'i' : 't';
|
||||
size_t iden;
|
||||
if (auto* name = std::get_if<IfcParse::InstanceReference>(&t)) {
|
||||
iden = *name;
|
||||
} else if (auto* inst = std::get_if<IfcUtil::IfcBaseClass*>(&t)) {
|
||||
iden = (*inst)->identity();
|
||||
} else if (auto* inst = std::get_if<express::Base>(&t)) {
|
||||
iden = (*inst).identity();
|
||||
}
|
||||
memcpy(val.data() + 2, &iden, s);
|
||||
return true;
|
||||
@@ -53,7 +53,7 @@ namespace {
|
||||
{
|
||||
// no attempt at alignment
|
||||
val.resize(t.size() * (sizeof(size_t) + 1) + 1);
|
||||
val[0] = TypeEncoder::encode_type<aggregate_of_instance::ptr>();
|
||||
val[0] = TypeEncoder::encode_type<std::vector<express::Base>>();
|
||||
char* ptr = val.data() + 1;
|
||||
for (auto it = t.begin(); it != t.end(); ++it) {
|
||||
*ptr = it->index() == 0 ? 'i' : 't';
|
||||
@@ -61,8 +61,8 @@ namespace {
|
||||
size_t iden = 0;
|
||||
if (auto* name = std::get_if<IfcParse::InstanceReference>(&*it)) {
|
||||
iden = *name;
|
||||
} else if (auto* inst = std::get_if<IfcUtil::IfcBaseClass*>(&*it)) {
|
||||
iden = (*inst)->identity();
|
||||
} else if (auto* inst = std::get_if<express::Base>(&*it)) {
|
||||
iden = (*inst).identity();
|
||||
}
|
||||
memcpy(ptr, &iden, sizeof(size_t));
|
||||
ptr += sizeof(size_t);
|
||||
@@ -73,7 +73,7 @@ namespace {
|
||||
bool serialize(std::string& val, const std::vector<std::vector<IfcParse::reference_or_simple_type>>& t)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss.put(TypeEncoder::encode_type<aggregate_of_aggregate_of_instance::ptr>());
|
||||
oss.put(TypeEncoder::encode_type<std::vector<std::vector<express::Base>>>());
|
||||
|
||||
auto write_size = [&oss](size_t sz) {
|
||||
std::string size_str;
|
||||
@@ -95,8 +95,8 @@ namespace {
|
||||
size_t iden = 0;
|
||||
if (auto* name = std::get_if<IfcParse::InstanceReference>(&*jt)) {
|
||||
iden = *name;
|
||||
} else if (auto* inst = std::get_if<IfcUtil::IfcBaseClass*>(&*jt)) {
|
||||
iden = (*inst)->identity();
|
||||
} else if (auto* inst = std::get_if<express::Base>(&*jt)) {
|
||||
iden = (*inst).identity();
|
||||
}
|
||||
std::string iden_str;
|
||||
iden_str.resize(sizeof(size_t));
|
||||
@@ -144,13 +144,13 @@ void RocksDbSerializer::write_streaming_() {
|
||||
|
||||
const bool is_header = decl->schema() == &Header_section_schema::get_schema();
|
||||
|
||||
std::vector<IfcUtil::IfcBaseClass*> simple_type_instances;
|
||||
std::vector<express::Base> simple_type_instances;
|
||||
|
||||
for (size_t i = 0; i < data.storage_->size(); i++) {
|
||||
auto val = data.get_attribute_value(nullptr, decl, 0, i);
|
||||
for (size_t i = 0; i < data->storage_->size(); i++) {
|
||||
auto val = data->get_attribute_value(i);
|
||||
val.apply_visitor([&](const auto& t) {
|
||||
using T = std::decay_t<decltype(t)>;
|
||||
if constexpr (std::is_same_v<T, IfcUtil::IfcBaseClass*>) {
|
||||
if constexpr (std::is_same_v<T, express::Base>) {
|
||||
// instance is per definition a simple type here, because instance
|
||||
// references are not resolved yet, but provided in vector of
|
||||
// references
|
||||
@@ -170,7 +170,7 @@ void RocksDbSerializer::write_streaming_() {
|
||||
(is_header ? decl->name() : std::to_string(p.first.name_)) + "|" +
|
||||
std::to_string(index);
|
||||
|
||||
if (storage.db->Get(storage.ropts, key, &tmp) == rocksdb::Status::OK() && tmp.size() == (sizeof(size_t) + 2) && tmp[0] == TypeEncoder::encode_type<IfcUtil::IfcBaseClass*>() && tmp[1] == 't')
|
||||
if (storage.db->Get(storage.ropts, key, &tmp) == rocksdb::Status::OK() && tmp.size() == (sizeof(size_t) + 2) && tmp[0] == TypeEncoder::encode_type<express::Base>() && tmp[1] == 't')
|
||||
{
|
||||
size_t iden;
|
||||
memcpy(&iden, tmp.data() + 2, sizeof(size_t));
|
||||
@@ -184,20 +184,20 @@ void RocksDbSerializer::write_streaming_() {
|
||||
using T = std::decay_t<decltype(v)>;
|
||||
|
||||
if constexpr (std::is_same_v<T, IfcParse::reference_or_simple_type>) {
|
||||
if (auto* inst = std::get_if<IfcUtil::IfcBaseClass*>(&v)) {
|
||||
if (auto* inst = std::get_if<express::Base>(&v)) {
|
||||
// So this never happens?
|
||||
simple_type_instances.push_back(*inst);
|
||||
}
|
||||
} else if constexpr (std::is_same_v<T, std::vector<IfcParse::reference_or_simple_type>>) {
|
||||
for (auto const& inner : v) {
|
||||
if (auto* inst = std::get_if<IfcUtil::IfcBaseClass*>(&inner)) {
|
||||
if (auto* inst = std::get_if<express::Base>(&inner)) {
|
||||
simple_type_instances.push_back(*inst);
|
||||
}
|
||||
}
|
||||
} else if constexpr (std::is_same_v<T, std::vector<std::vector<IfcParse::reference_or_simple_type>>>) {
|
||||
for (auto const& inner : v) {
|
||||
for (auto const& innermost : inner) {
|
||||
if (auto* inst = std::get_if<IfcUtil::IfcBaseClass*>(&innermost)) {
|
||||
if (auto* inst = std::get_if<express::Base>(&innermost)) {
|
||||
simple_type_instances.push_back(*inst);
|
||||
}
|
||||
}
|
||||
@@ -236,27 +236,28 @@ void RocksDbSerializer::write_streaming_() {
|
||||
}, p.second);
|
||||
}
|
||||
|
||||
for (const auto* inst : simple_type_instances) {
|
||||
for (const auto& inst : simple_type_instances) {
|
||||
std::string s(sizeof(size_t), ' ');
|
||||
size_t v = inst->declaration().index_in_schema();
|
||||
size_t v = inst.declaration().index_in_schema();
|
||||
memcpy(s.data(), &v, sizeof(size_t));
|
||||
|
||||
storage.db->Put(
|
||||
storage.wopts,
|
||||
(inst->declaration().as_entity() ? "i|" : "t|") + std::to_string(inst->identity()) + "|_", s);
|
||||
(inst.declaration().as_entity() ? "i|" : "t|") + std::to_string(inst.identity()) + "|_", s);
|
||||
|
||||
if (type_identities_wrote_as_refs.find(inst->identity()) != type_identities_wrote_as_refs.end()) {
|
||||
if (type_identities_wrote_as_refs.find(inst.identity()) != type_identities_wrote_as_refs.end()) {
|
||||
// already written as reference, skip
|
||||
// only applies to the value though, the type declaration still needs to be written
|
||||
continue;
|
||||
}
|
||||
|
||||
auto val = inst->get_attribute_value(0);
|
||||
if (val.array_.storage_ptr->size() > 0) {
|
||||
auto val = inst.get_attribute_value(0);
|
||||
// @todo if statement?
|
||||
// if (val.array_.storage_ptr->size() > 0) {
|
||||
val.apply_visitor([&](const auto& t) {
|
||||
rocks_db_attribute_storage{}.set(&storage, &inst->declaration(), inst->identity(), 0, t);
|
||||
rocks_db_attribute_storage{}.set(&storage, &inst.declaration(), inst.identity(), 0, t);
|
||||
});
|
||||
}
|
||||
// }
|
||||
|
||||
// @nb we also need to delete them
|
||||
// not anymore, as they are now registered as unique_ptr in the in_memory_file_storage
|
||||
@@ -286,89 +287,9 @@ void RocksDbSerializer::write_streaming_() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RocksDbSerializer::write_non_streaming_() {
|
||||
// Build a map of instances and their references/dependencies
|
||||
std::map<uint32_t, std::set<uint32_t>> dependencies, dependencies_inv;
|
||||
std::visit([&dependencies](const auto& m) {
|
||||
if constexpr (std::is_same_v<std::decay_t<decltype(m)>, IfcParse::impl::in_memory_file_storage>) {
|
||||
for (const auto& ps : m.byref_excl_) {
|
||||
for (const auto& p : ps.second) {
|
||||
dependencies[p].insert(std::get<0>(ps.first));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, std::get<IfcParse::IfcFile*>(file_)->storage_);
|
||||
// Add bottom-rank nodes, inv mapping does not contain them
|
||||
for (const auto& p : *std::get<IfcParse::IfcFile*>(file_)) {
|
||||
dependencies[p.first];
|
||||
}
|
||||
|
||||
for (auto& ps : dependencies) {
|
||||
for (auto& p : ps.second) {
|
||||
dependencies_inv[p].insert(ps.first);
|
||||
}
|
||||
}
|
||||
|
||||
// Do a topological sort over the nodes
|
||||
std::vector<uint32_t> deps_topo_order;
|
||||
while (dependencies.size() > 0) {
|
||||
std::vector<uint32_t> no_deps;
|
||||
for (auto& ps : dependencies) {
|
||||
if (ps.second.size() == 0) {
|
||||
no_deps.push_back(ps.first);
|
||||
}
|
||||
}
|
||||
|
||||
if (no_deps.size() == 0) {
|
||||
throw std::runtime_error("cyclic dependencies in model, unable to serialize");
|
||||
}
|
||||
|
||||
for (auto& i : no_deps) {
|
||||
deps_topo_order.push_back(i);
|
||||
}
|
||||
|
||||
// mutate mapping
|
||||
for (auto& i : no_deps) {
|
||||
dependencies.erase(i);
|
||||
}
|
||||
for (auto& i : no_deps) {
|
||||
for (auto& j : dependencies_inv[i]) {
|
||||
auto it = dependencies.find(j);
|
||||
if (it != dependencies.end()) {
|
||||
it->second.erase(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add them in topological order, so that add() never recurses into something not previously visited
|
||||
for (auto& i : deps_topo_order) {
|
||||
output_file_->addEntity(std::get<IfcParse::IfcFile*>(file_)->instance_by_id(i), i);
|
||||
}
|
||||
|
||||
// Copy inverses
|
||||
/*
|
||||
// These are now back to being added in addEntity() / set_attribute_value()
|
||||
std::visit([this](const auto& m) {
|
||||
if constexpr (std::is_same_v<std::decay_t<decltype(m)>, IfcParse::impl::in_memory_file_storage>) {
|
||||
for (auto& p : m.byref_excl_) {
|
||||
// This is much slower than need be, because:
|
||||
// - insert() first checks for existance [we know it does not] because insert() should not overwrite
|
||||
// - insert() returns an pair<iterator, bool> [which is not used] which requires an expensive seek after the put.
|
||||
// This is left as-is for now, because anyway we want to build a streaming converter
|
||||
std::get<IfcParse::impl::rocks_db_file_storage>(output_file_->storage_).byref_excl_.insert(p);
|
||||
}
|
||||
}
|
||||
}, file_->storage_);
|
||||
*/
|
||||
|
||||
delete output_file_;
|
||||
}
|
||||
|
||||
void RocksDbSerializer::finalize() {
|
||||
if (file_.index() == 0) {
|
||||
write_non_streaming_();
|
||||
throw std::runtime_error("Non-streaming mode no longer supported");
|
||||
} else {
|
||||
write_streaming_();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user