| 2579 | } |
| 2580 | |
| 2581 | aggregate_of_instance::ptr IfcFile::getInverse(int instance_id, const IfcParse::declaration* type, int attribute_index) { |
| 2582 | if (type == nullptr && attribute_index == -1) { |
| 2583 | return instances_by_reference(instance_id); |
| 2584 | } |
| 2585 | |
| 2586 | aggregate_of_instance::ptr return_value(new aggregate_of_instance); |
| 2587 | |
| 2588 | visit_subtypes(type->as_entity(), [this, attribute_index, instance_id, &return_value](const IfcParse::declaration* ent) { |
| 2589 | |
| 2590 | std::visit([&return_value, this, attribute_index, instance_id, ent](const auto& x) { |
| 2591 | if constexpr (std::is_same_v<std::decay_t<decltype(x)>, std::monostate>) { |
| 2592 | } else if constexpr (std::is_same_v<std::decay_t<decltype(x)>, impl::in_memory_file_storage>) { |
| 2593 | if (attribute_index == -1) { |
| 2594 | auto lower = x.byref_excl_.lower_bound({ instance_id, ent->index_in_schema(), -1 }); |
| 2595 | auto upper = x.byref_excl_.upper_bound({ instance_id, ent->index_in_schema(), std::numeric_limits<short>::max() }); |
| 2596 | |
| 2597 | for (auto it = lower; it != upper; ++it) { |
| 2598 | for (auto& i : it->second) { |
| 2599 | return_value->push(instance_by_id(i)); |
| 2600 | } |
| 2601 | } |
| 2602 | } else { |
| 2603 | auto it = x.byref_excl_.find({ instance_id, ent->index_in_schema(), attribute_index }); |
| 2604 | if (it != x.byref_excl_.end()) { |
| 2605 | for (auto& i : it->second) { |
| 2606 | return_value->push(instance_by_id(i)); |
| 2607 | } |
| 2608 | } |
| 2609 | } |
| 2610 | } |
| 2611 | #ifdef IFOPSH_WITH_ROCKSDB |
| 2612 | else if constexpr (std::is_same_v<std::decay_t<decltype(x)>, impl::rocks_db_file_storage>) { |
| 2613 | if (attribute_index == -1) { |
| 2614 | // @todo no lower/upper_bounds() implemented yet |
| 2615 | auto prefix = "v|" + std::to_string(instance_id) + "|" + std::to_string(ent->index_in_schema()) + "|"; |
| 2616 | auto it = std::unique_ptr<rocksdb::Iterator>(x.db->NewIterator(rocksdb::ReadOptions())); |
| 2617 | it->Seek(prefix); |
| 2618 | while (it->Valid() && it->key().starts_with(prefix)) { |
| 2619 | std::vector<uint32_t> vals(it->value().size() / sizeof(uint32_t)); |
| 2620 | memcpy(vals.data(), it->value().data(), it->value().size()); |
| 2621 | for (auto& v : vals) { |
| 2622 | return_value->push(instance_by_id(v)); |
| 2623 | } |
| 2624 | it->Next(); |
| 2625 | } |
| 2626 | } else { |
| 2627 | auto it = x.byref_excl_.find({ instance_id, ent->index_in_schema(), attribute_index }); |
| 2628 | if (it != x.byref_excl_.end()) { |
| 2629 | for (auto& i : it->second) { |
| 2630 | return_value->push(instance_by_id(i)); |
| 2631 | } |
| 2632 | } |
| 2633 | } |
| 2634 | } |
| 2635 | #endif |
| 2636 | }, storage_); |
| 2637 | }); |
| 2638 |
no test coverage detected