Write GlobalId index when serializing to RocksDB

rocks_db_file_storage already exposes a `g|`-prefixed guid -> instance
name map, but RocksDbSerializer never populated it, so by_guid() on a
converted file always threw.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-08-06 10:16:34 +10:00
parent 38e0e0e297
commit 74b405a9f7
2 changed files with 27 additions and 0 deletions
@@ -115,6 +115,11 @@ def test_rocks():
b = f.key_value_store_query(f"t|{iden}|0")[1:]
assert set(struct.unpack("Q", b[i : i + 8])[0] for i in range(1, len(b), 9)) == {136, 138}
g = ifcopenshell.open(fn)
for inst in g.by_type("IfcRoot"):
assert f.by_guid(inst.GlobalId).id() == inst.id()
del g
del f
gc.collect()
+22
View File
@@ -113,6 +113,10 @@ void RocksDbSerializer::write_streaming_() {
std::string tmp;
// Resolved lazily from the first non-header declaration encountered, because
// the schema is only known once the header has been read.
const ifcopenshell::declaration* ifcroot_type = nullptr;
ifcopenshell::instance_streamer streamer(input_filename_);
// We do not want to coerce attribute counts here, because we want
@@ -279,6 +283,24 @@ void RocksDbSerializer::write_streaming_() {
memcpy(s.data(), &v, sizeof(size_t));
storage.db->Merge(storage.wopts, "t|" + std::to_string(decl->index_in_schema()), s);
}
// GlobalId as numeric ref to instance name, so that the guid map in
// rocks_db_file_storage can resolve by_guid() lookups.
if (ifcroot_type == nullptr) {
ifcroot_type = decl->schema()->declaration_by_name("IfcRoot");
}
if (decl->is(*ifcroot_type)) {
// @nb attribute counts are not coerced, so the attribute may be absent
const bool has_guid = data->storage_->size() > 0 && data->get_attribute_value(0).type() == ifcopenshell::Argument_STRING;
if (has_guid) {
size_t v = name;
std::string s(sizeof(size_t), ' ');
memcpy(s.data(), &v, sizeof(size_t));
storage.db->Put(storage.wopts, "g|" + (std::string)data->get_attribute_value(0), s);
} else {
::logger::root().error("Instance #" + std::to_string(name) + " has no GlobalId, omitted from guid index");
}
}
}
streamer.references().clear();