mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 18:16:40 +00:00
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:
@@ -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()
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user