mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 06:58:56 +00:00
Further small memory optimizations
This commit is contained in:
@@ -264,6 +264,7 @@ bool impl::serialize(std::string& val, const aggregate_of_instance::ptr& t)
|
|||||||
|
|
||||||
bool impl::serialize(std::string& val, const aggregate_of_aggregate_of_instance::ptr& t)
|
bool impl::serialize(std::string& val, const aggregate_of_aggregate_of_instance::ptr& t)
|
||||||
{
|
{
|
||||||
|
// @todo
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -386,11 +386,6 @@ struct AttributeValue {
|
|||||||
|
|
||||||
struct rocks_db_attribute_storage {
|
struct rocks_db_attribute_storage {
|
||||||
public:
|
public:
|
||||||
size_t size(void*, const IfcParse::declaration*, std::size_t identity) const {
|
|
||||||
// @todo is this actually needed?
|
|
||||||
return 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @todo void* is obviously very ugly here
|
// @todo void* is obviously very ugly here
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void set(void* storage, const IfcParse::declaration*, std::size_t identity, std::size_t index, const T& value);
|
void set(void* storage, const IfcParse::declaration*, std::size_t identity, std::size_t index, const T& value);
|
||||||
@@ -407,20 +402,19 @@ public:
|
|||||||
|
|
||||||
class IFC_PARSE_API IfcEntityInstanceData {
|
class IFC_PARSE_API IfcEntityInstanceData {
|
||||||
public:
|
public:
|
||||||
// @todo since rocks_db_attribute_storage has no members anymore, change to in_memory_attribute_storage*?
|
// Since rocks_db_attribute_storage has no members this is not a variant<in_memory, rocks> but in_memory*, where nullptr means a rocks_db_attribute_storage is constructed on the fly given the context from instance data.
|
||||||
// 24 -> 8 bytes...
|
in_memory_attribute_storage* storage_;
|
||||||
std::variant<in_memory_attribute_storage, rocks_db_attribute_storage> storage_;
|
|
||||||
|
|
||||||
IfcEntityInstanceData(in_memory_attribute_storage&& storage)
|
IfcEntityInstanceData(in_memory_attribute_storage&& storage)
|
||||||
: storage_(std::move(storage))
|
: storage_(new in_memory_attribute_storage(std::move(storage)))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
IfcEntityInstanceData(rocks_db_attribute_storage&& storage)
|
IfcEntityInstanceData(rocks_db_attribute_storage&&)
|
||||||
: storage_(std::move(storage))
|
: storage_(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
IfcEntityInstanceData(IfcEntityInstanceData&& other) noexcept
|
IfcEntityInstanceData(IfcEntityInstanceData&& other) noexcept
|
||||||
: storage_(std::move(other.storage_))
|
: storage_(other.storage_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// No copy-constructor anymore because we need the instance for storage model context
|
// No copy-constructor anymore because we need the instance for storage model context
|
||||||
@@ -428,7 +422,7 @@ class IFC_PARSE_API IfcEntityInstanceData {
|
|||||||
|
|
||||||
IfcEntityInstanceData& operator=(IfcEntityInstanceData&& other) {
|
IfcEntityInstanceData& operator=(IfcEntityInstanceData&& other) {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
storage_ = std::move(other.storage_);
|
storage_ = other.storage_;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -437,45 +431,29 @@ class IFC_PARSE_API IfcEntityInstanceData {
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void set_attribute_value(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index, T&& value) {
|
void set_attribute_value(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index, T&& value) {
|
||||||
std::visit([&index, &value, storage, decl, identity](auto& x) {
|
if (storage_) {
|
||||||
if constexpr (std::is_same_v<std::decay_t<decltype(x)>, in_memory_attribute_storage>) {
|
storage_->set(index, value);
|
||||||
return x.set(index, value);
|
} else {
|
||||||
} else {
|
rocks_db_attribute_storage{}.set(storage, decl, identity, index, value);
|
||||||
return x.set(storage, decl, identity, index, value);
|
}
|
||||||
}
|
|
||||||
}, storage_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool has_attribute_value(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index) const {
|
bool has_attribute_value(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index) const {
|
||||||
return std::visit([&index, storage, decl, identity](const auto& x) {
|
if (storage_) {
|
||||||
if constexpr (std::is_same_v<std::decay_t<decltype(x)>, in_memory_attribute_storage>) {
|
return storage_->has<T>(index);
|
||||||
return x.has<T>(index);
|
} else {
|
||||||
} else {
|
return rocks_db_attribute_storage{}.has<T>(storage, decl, identity, index);
|
||||||
return x.has<T>(storage, decl, identity, index);
|
}
|
||||||
}
|
|
||||||
}, storage_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Visitor>
|
template<typename Visitor>
|
||||||
auto apply_visitor(void* storage, const IfcParse::declaration* decl, std::size_t identity, Visitor&& visitor, std::size_t index) const {
|
auto apply_visitor(void* storage, const IfcParse::declaration* decl, std::size_t identity, Visitor&& visitor, std::size_t index) const {
|
||||||
return std::visit([&index, &visitor, storage, decl, identity](const auto& x) {
|
if (storage_) {
|
||||||
if constexpr (std::is_same_v<std::decay_t<decltype(x)>, in_memory_attribute_storage>) {
|
return storage_->apply_visitor(std::forward<Visitor>(visitor), index);
|
||||||
return x.apply_visitor(std::forward<Visitor>(visitor), index);
|
} else {
|
||||||
} else {
|
return rocks_db_attribute_storage{}.apply_visitor(storage, decl, identity, index, std::forward<Visitor>(visitor));
|
||||||
return x.apply_visitor(storage, decl, identity, index, std::forward<Visitor>(visitor));
|
}
|
||||||
}
|
|
||||||
}, storage_);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size(void* storage, const IfcParse::declaration* decl, std::size_t identity) const {
|
|
||||||
return std::visit([storage, decl, identity](const auto& x) {
|
|
||||||
if constexpr (std::is_same_v<std::decay_t<decltype(x)>, in_memory_attribute_storage>) {
|
|
||||||
return x.size();
|
|
||||||
} else {
|
|
||||||
return x.size(storage, decl, identity);
|
|
||||||
}
|
|
||||||
}, storage_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void toString(void* storage, const IfcParse::declaration*, std::size_t identity, std::ostream&, bool upper = false) const;
|
void toString(void* storage, const IfcParse::declaration*, std::size_t identity, std::ostream&, bool upper = false) const;
|
||||||
|
|||||||
@@ -349,9 +349,16 @@ IfcParse::impl::rocks_db_file_storage::rocksdb_types_iterator::value_type const&
|
|||||||
}
|
}
|
||||||
|
|
||||||
IfcUtil::IfcBaseClass* IfcParse::impl::rocks_db_file_storage::assert_existance(size_t number, instance_ref r) {
|
IfcUtil::IfcBaseClass* IfcParse::impl::rocks_db_file_storage::assert_existance(size_t number, instance_ref r) {
|
||||||
decltype(instance_cache_)::const_iterator it = instance_cache_.find({ r, number });
|
if (r == IfcParse::impl::rocks_db_file_storage::entityinstance_ref) {
|
||||||
if (it != instance_cache_.end()) {
|
auto it = instance_cache_.find(number);
|
||||||
return it->second;
|
if (it != instance_cache_.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto it = type_instance_cache_.find(number);
|
||||||
|
if (it != type_instance_cache_.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string v;
|
std::string v;
|
||||||
@@ -369,10 +376,19 @@ IfcUtil::IfcBaseClass* IfcParse::impl::rocks_db_file_storage::assert_existance(s
|
|||||||
throw std::runtime_error("Incorrect reference");
|
throw std::runtime_error("Incorrect reference");
|
||||||
}
|
}
|
||||||
IfcEntityInstanceData data(rocks_db_attribute_storage{});
|
IfcEntityInstanceData data(rocks_db_attribute_storage{});
|
||||||
auto inst = file->schema()->instantiate(decl, std::move(data));
|
IfcUtil::IfcBaseClass* inst;
|
||||||
|
if (file->instantiate_typed_instances) {
|
||||||
|
inst = file->schema()->instantiate(decl, std::move(data));
|
||||||
|
} else {
|
||||||
|
inst = new IfcUtil::IfcLateBoundEntity(decl, std::move(data));
|
||||||
|
}
|
||||||
inst->id_ = number;
|
inst->id_ = number;
|
||||||
inst->file_ = file;
|
inst->file_ = file;
|
||||||
instance_cache_.insert({ {r, number}, inst });
|
if (r == IfcParse::impl::rocks_db_file_storage::entityinstance_ref) {
|
||||||
|
instance_cache_.insert({ number, inst });
|
||||||
|
} else {
|
||||||
|
type_instance_cache_.insert({ number, inst });
|
||||||
|
}
|
||||||
return inst;
|
return inst;
|
||||||
} else {
|
} else {
|
||||||
throw IfcException("Instance #" + boost::lexical_cast<std::string>(number) + " not found");
|
throw IfcException("Instance #" + boost::lexical_cast<std::string>(number) + " not found");
|
||||||
|
|||||||
+6
-14
@@ -60,21 +60,12 @@ namespace {
|
|||||||
|
|
||||||
|
|
||||||
virtual bool Merge(const rocksdb::Slice&,
|
virtual bool Merge(const rocksdb::Slice&,
|
||||||
const rocksdb::Slice* existing_value,
|
const rocksdb::Slice*,
|
||||||
const rocksdb::Slice& value,
|
const rocksdb::Slice&,
|
||||||
std::string* new_value,
|
std::string*,
|
||||||
rocksdb::Logger*) const override
|
rocksdb::Logger*) const override
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
/*
|
|
||||||
if (existing_value) {
|
|
||||||
new_value->assign(existing_value->data(), existing_value->size());
|
|
||||||
new_value->append(value.data(), value.size());
|
|
||||||
} else {
|
|
||||||
new_value->assign(value.data(), value.size());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const char* Name() const override {
|
virtual const char* Name() const override {
|
||||||
@@ -359,8 +350,8 @@ namespace impl {
|
|||||||
// to make sure that instance pointer are constant during file lifetime
|
// to make sure that instance pointer are constant during file lifetime
|
||||||
// cache instances because we want stable pointers
|
// cache instances because we want stable pointers
|
||||||
// @todo this is silly, but we cannot have the same type, this should be just a pointer then on the IfcFile side?
|
// @todo this is silly, but we cannot have the same type, this should be just a pointer then on the IfcFile side?
|
||||||
typedef std::map<std::pair<instance_ref, uint32_t>, IfcUtil::IfcBaseClass*> entity_by_iden_cache_t;
|
typedef std::map<uint32_t, IfcUtil::IfcBaseClass*> entity_by_iden_cache_t;
|
||||||
entity_by_iden_cache_t instance_cache_;
|
entity_by_iden_cache_t instance_cache_, type_instance_cache_;
|
||||||
|
|
||||||
// @todo all these size_ts should probably be uint32_t for consistency with in-mem storage
|
// @todo all these size_ts should probably be uint32_t for consistency with in-mem storage
|
||||||
|
|
||||||
@@ -619,6 +610,7 @@ public:
|
|||||||
|
|
||||||
bool check_existance_before_adding = true;
|
bool check_existance_before_adding = true;
|
||||||
bool calculate_unit_factors = true;
|
bool calculate_unit_factors = true;
|
||||||
|
bool instantiate_typed_instances = true;
|
||||||
|
|
||||||
// @todo temporarily public for header
|
// @todo temporarily public for header
|
||||||
storage_t storage_;
|
storage_t storage_;
|
||||||
|
|||||||
@@ -2694,15 +2694,11 @@ IfcEntityInstanceData::IfcEntityInstanceData(const IfcEntityInstanceData& data)
|
|||||||
|
|
||||||
AttributeValue IfcEntityInstanceData::get_attribute_value(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const
|
AttributeValue IfcEntityInstanceData::get_attribute_value(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const
|
||||||
{
|
{
|
||||||
return std::visit([this, storage, decl, identity, index](const auto& x) {
|
if (storage_) {
|
||||||
if constexpr (std::is_same_v<std::decay_t<decltype(x)>, in_memory_attribute_storage>) {
|
return AttributeValue(storage_, (uint8_t)index);
|
||||||
return AttributeValue(&x, (uint8_t)index);
|
} else {
|
||||||
} else if constexpr (std::is_same_v<std::decay_t<decltype(x)>, rocks_db_attribute_storage>) {
|
return AttributeValue((IfcParse::impl::rocks_db_file_storage*)storage, identity, decl->as_entity() ? 1 : 0, index);
|
||||||
return AttributeValue((IfcParse::impl::rocks_db_file_storage*) storage, identity, decl->as_entity() ? 1 : 0, index);
|
}
|
||||||
} else {
|
|
||||||
return AttributeValue{};
|
|
||||||
}
|
|
||||||
}, storage_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IfcParse::impl::rocks_db_file_storage::read_schema(const IfcParse::schema_definition*& schema) {
|
bool IfcParse::impl::rocks_db_file_storage::read_schema(const IfcParse::schema_definition*& schema) {
|
||||||
|
|||||||
Reference in New Issue
Block a user