diff --git a/src/serializers/RocksDbSerializer.cpp b/src/serializers/RocksDbSerializer.cpp index 74c83ac861..9fd9f62546 100644 --- a/src/serializers/RocksDbSerializer.cpp +++ b/src/serializers/RocksDbSerializer.cpp @@ -122,10 +122,24 @@ void RocksDbSerializer::write_streaming_() { }); } + std::set type_identities_wrote_as_refs; + for (auto& p : streamer.references()) { // @nb cast to int in order not be interpreted as a char when appending to string int index = p.first.index_; + auto key = (is_header ? "h|" : (decl->as_entity() ? "i|" : "t|")) + + (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() && tmp[1] == 't') + { + size_t iden; + memcpy(&iden, tmp.data() + 2, sizeof(size_t)); + key = "t|" + std::to_string(iden) + "|0"; + type_identities_wrote_as_refs.insert(iden); + } + std::visit([&](const auto& v) { serialize(tmp, v); @@ -155,9 +169,7 @@ void RocksDbSerializer::write_streaming_() { storage.db->Put( storage.wopts, - (is_header ? "h|" : (decl->as_entity() ? "i|" : "t|")) + - (is_header ? decl->name() : std::to_string(p.first.name_)) + "|" + - std::to_string(index), tmp); + key, tmp); auto write_inverse = [&](const IfcParse::reference_or_simple_type& v) { if (auto* ref = std::get_if(&v)) { @@ -187,6 +199,10 @@ void RocksDbSerializer::write_streaming_() { } for (const auto* inst : simple_type_instances) { + if (type_identities_wrote_as_refs.find(inst->identity()) != type_identities_wrote_as_refs.end()) { + // already written as reference, skip + continue; + } std::string s(sizeof(size_t), ' '); size_t v = inst->declaration().index_in_schema(); memcpy(s.data(), &v, sizeof(size_t)); diff --git a/src/serializers/RocksDbSerializer.h b/src/serializers/RocksDbSerializer.h index 89bf9ab5ca..b86ad7e61b 100644 --- a/src/serializers/RocksDbSerializer.h +++ b/src/serializers/RocksDbSerializer.h @@ -1,3 +1,5 @@ +#ifndef ROCKSDBSERIALIZER_H +#define ROCKSDBSERIALIZER_H #ifdef WITH_ROCKSDB #include "../serializers/serializers_api.h" @@ -28,4 +30,5 @@ public: void setFile(IfcParse::IfcFile*) { throw IfcParse::IfcException("Should be supplied on construction"); } }; +#endif #endif \ No newline at end of file