mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 03:44:34 +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:]
|
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}
|
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
|
del f
|
||||||
gc.collect()
|
gc.collect()
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,10 @@ void RocksDbSerializer::write_streaming_() {
|
|||||||
|
|
||||||
std::string tmp;
|
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_);
|
ifcopenshell::instance_streamer streamer(input_filename_);
|
||||||
|
|
||||||
// We do not want to coerce attribute counts here, because we want
|
// 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));
|
memcpy(s.data(), &v, sizeof(size_t));
|
||||||
storage.db->Merge(storage.wopts, "t|" + std::to_string(decl->index_in_schema()), s);
|
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();
|
streamer.references().clear();
|
||||||
|
|||||||
Reference in New Issue
Block a user