| 504 | } |
| 505 | |
| 506 | void IfcParse::impl::rocks_db_file_storage::process_deletion_inverse(IfcUtil::IfcBaseClass* inst) |
| 507 | { |
| 508 | #ifdef IFOPSH_WITH_ROCKSDB |
| 509 | auto id = inst->id(); |
| 510 | |
| 511 | { |
| 512 | // compute next prefix that does not start with v|{id}| |
| 513 | auto prefix = "v|" + std::to_string(id) + "|"; |
| 514 | auto it = std::unique_ptr<rocksdb::Iterator>(db->NewIterator(rocksdb::ReadOptions())); |
| 515 | it->Seek(prefix); |
| 516 | while (it->Valid()) { |
| 517 | it->Next(); |
| 518 | if (!it->key().starts_with(prefix)) { |
| 519 | break; |
| 520 | } |
| 521 | } |
| 522 | |
| 523 | rocksdb::WriteBatch batch; |
| 524 | batch.DeleteRange(prefix, it->key()); |
| 525 | db->Write(wopts, &batch); |
| 526 | } |
| 527 | |
| 528 | // This is based on traversal which needs instances to still be contained in the map. |
| 529 | // another option would be to keep byid intact for the remainder of this loop |
| 530 | aggregate_of_instance::ptr entity_attributes = traverse(inst, 1); |
| 531 | for (aggregate_of_instance::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) { |
| 532 | IfcUtil::IfcBaseClass* entity_attribute = *it; |
| 533 | if (entity_attribute == inst) { |
| 534 | continue; |
| 535 | } |
| 536 | const unsigned int name = entity_attribute->id(); |
| 537 | // Do not update inverses for simple types (which have id()==0 in IfcOpenShell). |
| 538 | if (name != 0) { |
| 539 | // Find instances entity -> other |
| 540 | // and update inverses from entity into other |
| 541 | |
| 542 | { |
| 543 | auto prefix = "v|" + std::to_string(name) + "|"; |
| 544 | auto it = std::unique_ptr<rocksdb::Iterator>(db->NewIterator(rocksdb::ReadOptions())); |
| 545 | it->Seek(prefix); |
| 546 | while (it->Valid() && it->key().starts_with(prefix)) { |
| 547 | std::string s = it->value().ToString(); |
| 548 | |
| 549 | // Iterator are snapshotted? So don't get invalidated? |
| 550 | std::vector<size_t> vals(s.size() / sizeof(size_t)); |
| 551 | memcpy(vals.data(), s.data(), s.size()); |
| 552 | vals.erase(std::find(vals.begin(), vals.end(), (size_t)id)); |
| 553 | s.resize(vals.size() * sizeof(size_t)); |
| 554 | memcpy(s.data(), vals.data(), s.size()); |
| 555 | db->Put(wopts, it->key(), s); |
| 556 | |
| 557 | it->Next(); |
| 558 | } |
| 559 | } |
| 560 | } |
| 561 | } |
| 562 | #endif |
| 563 | } |