mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
Exploration of using rocksdb as file+instance storage
This commit is contained in:
@@ -25,6 +25,13 @@
|
||||
#include "aggregate_of_instance.h"
|
||||
#include "IfcSchema.h"
|
||||
|
||||
#pragma push_macro("Handle")
|
||||
#undef Handle
|
||||
|
||||
#include <rocksdb/db.h>
|
||||
|
||||
#pragma pop_macro("Handle")
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/logic/tribool.hpp>
|
||||
@@ -36,7 +43,7 @@ private:
|
||||
size_t index_;
|
||||
public:
|
||||
|
||||
EnumerationReference(const IfcParse::enumeration_type* enumeration, size_t index)
|
||||
EnumerationReference(const IfcParse::enumeration_type* enumeration = nullptr, size_t index = 0)
|
||||
: enumeration_(enumeration)
|
||||
, index_(index)
|
||||
{}
|
||||
@@ -58,7 +65,12 @@ class Derived {};
|
||||
class empty_aggregate_t {};
|
||||
class empty_aggregate_of_aggregate_t {};
|
||||
|
||||
typedef VariantArray <
|
||||
template<typename... Args>
|
||||
struct parameter_pack {
|
||||
static constexpr size_t size = sizeof...(Args);
|
||||
};
|
||||
|
||||
typedef parameter_pack <
|
||||
// A null argument, it will always serialize to $
|
||||
Blank,
|
||||
// @todo Derived is not really necessary anymore, just serialize correctly based on schema
|
||||
@@ -113,26 +125,75 @@ typedef VariantArray <
|
||||
std::vector<std::vector<double>>,
|
||||
// An aggregate of an aggregate of entities. E.g. ((#1, #2), (#3))
|
||||
aggregate_of_aggregate_of_instance::ptr
|
||||
> storage_t;
|
||||
> type_variant_parameter_pack;
|
||||
|
||||
template<typename Pack>
|
||||
struct pack_to_variant_array;
|
||||
|
||||
template<typename... Args>
|
||||
struct pack_to_variant_array<parameter_pack<Args...>> {
|
||||
using type = VariantArray<Args...>;
|
||||
};
|
||||
|
||||
using in_memory_attribute_storage = pack_to_variant_array<type_variant_parameter_pack>::type;
|
||||
|
||||
template <typename Pack>
|
||||
struct TypeEncoder_t;
|
||||
|
||||
template <typename... Types>
|
||||
struct TypeEncoder_t<parameter_pack<Types...>> {
|
||||
template <typename U>
|
||||
static char encode_type() {
|
||||
return 'A' + ::impl::TypeIndex_v<U, Types...>;
|
||||
}
|
||||
};
|
||||
|
||||
using TypeEncoder = TypeEncoder_t<type_variant_parameter_pack>;
|
||||
|
||||
struct MutableAttributeValue {
|
||||
int name_;
|
||||
uint8_t index_;
|
||||
};
|
||||
|
||||
namespace IfcParse {
|
||||
namespace impl {
|
||||
class rocks_db_file_storage;
|
||||
}
|
||||
}
|
||||
|
||||
// short lived
|
||||
struct AttributeValue {
|
||||
const storage_t* array_;
|
||||
uint8_t index_;
|
||||
|
||||
uint8_t storage_model_ = 0;
|
||||
size_t instance_name_;
|
||||
// @todo couple with db_ptr;
|
||||
IfcParse::schema_definition* schema_;
|
||||
union pointer_type {
|
||||
const in_memory_attribute_storage* storage_ptr;
|
||||
IfcParse::impl::rocks_db_file_storage* db_ptr;
|
||||
pointer_type(IfcParse::impl::rocks_db_file_storage* db) : db_ptr(db) {}
|
||||
pointer_type(const in_memory_attribute_storage* ims) : storage_ptr(ims) {}
|
||||
};
|
||||
pointer_type array_;
|
||||
|
||||
AttributeValue()
|
||||
: array_(nullptr)
|
||||
, index_(0)
|
||||
: index_(0)
|
||||
, array_((const in_memory_attribute_storage*)nullptr)
|
||||
, storage_model_(0)
|
||||
{}
|
||||
|
||||
AttributeValue(const storage_t* arr, uint8_t index)
|
||||
: array_(arr)
|
||||
, index_(index)
|
||||
AttributeValue(const in_memory_attribute_storage* arr, uint8_t index)
|
||||
: index_(index)
|
||||
, array_(arr)
|
||||
, storage_model_(0)
|
||||
{}
|
||||
|
||||
AttributeValue(IfcParse::schema_definition* schema, IfcParse::impl::rocks_db_file_storage* db, size_t instance_name, uint8_t index)
|
||||
: index_(index)
|
||||
, array_(db)
|
||||
, storage_model_(1)
|
||||
, instance_name_(instance_name)
|
||||
, schema_(schema)
|
||||
{}
|
||||
|
||||
operator int() const;
|
||||
@@ -153,17 +214,60 @@ struct AttributeValue {
|
||||
operator std::vector<std::vector<double>>() const;
|
||||
operator boost::shared_ptr<aggregate_of_aggregate_of_instance>() const;
|
||||
|
||||
operator EnumerationReference() const;
|
||||
|
||||
bool isNull() const;
|
||||
unsigned int size() const;
|
||||
|
||||
IfcUtil::ArgumentType type() const;
|
||||
};
|
||||
|
||||
struct rocks_db_attribute_storage {
|
||||
private:
|
||||
IfcParse::impl::rocks_db_file_storage* fs;
|
||||
|
||||
template<typename Visitor, std::size_t Index>
|
||||
auto apply_visitor_impl(Visitor&& visitor, std::size_t idx, std::integral_constant<std::size_t, Index>) const {
|
||||
return apply_visitor_impl(std::forward<Visitor>(visitor), idx, std::integral_constant<std::size_t, Index - 1>{});
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
void apply_visitor_impl(Visitor&&, std::size_t, std::integral_constant<std::size_t, 0>) const {
|
||||
throw std::runtime_error("Invalid variant index");
|
||||
}
|
||||
|
||||
public:
|
||||
size_t size() const {
|
||||
// @todo
|
||||
return 8;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void set(std::size_t index, T&& value) {
|
||||
// @todo
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool has(std::size_t index) const {
|
||||
// @todo
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
auto apply_visitor(Visitor&& visitor, std::size_t index) const {
|
||||
return apply_visitor_impl(std::forward<Visitor>(visitor), index, std::integral_constant<std::size_t, type_variant_parameter_pack::size>{});
|
||||
}
|
||||
};
|
||||
|
||||
class IFC_PARSE_API IfcEntityInstanceData {
|
||||
public:
|
||||
storage_t storage_;
|
||||
std::variant<in_memory_attribute_storage, rocks_db_attribute_storage> storage_;
|
||||
|
||||
IfcEntityInstanceData(storage_t&& storage)
|
||||
IfcEntityInstanceData(in_memory_attribute_storage&& storage)
|
||||
: storage_(std::move(storage))
|
||||
{}
|
||||
|
||||
IfcEntityInstanceData(rocks_db_attribute_storage&& storage)
|
||||
: storage_(std::move(storage))
|
||||
{}
|
||||
|
||||
@@ -182,15 +286,29 @@ class IFC_PARSE_API IfcEntityInstanceData {
|
||||
|
||||
AttributeValue get_attribute_value(size_t index) const;
|
||||
|
||||
/*
|
||||
template <typename T>
|
||||
void set_attribute_value(size_t index, const T& t);
|
||||
template<typename T>
|
||||
void set_attribute_value(std::size_t index, T&& value) {
|
||||
std::visit([&index, &value](auto& x) {
|
||||
return x.set(index, value);
|
||||
}, storage_);
|
||||
}
|
||||
|
||||
void set_attribute_value(size_t index, AttributeValue&, IfcUtil::ArgumentType attr_type = IfcUtil::Argument_UNKNOWN);
|
||||
*/
|
||||
template<typename T>
|
||||
bool has_attribute_value(std::size_t index) const {
|
||||
return std::visit([&index](const auto& x) {
|
||||
return x.has<T>(index);
|
||||
}, storage_);
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
auto apply_visitor(Visitor&& visitor, std::size_t index) const {
|
||||
return std::visit([&index, &visitor](const auto& x) {
|
||||
return x.apply_visitor(std::forward<Visitor>(visitor), index);
|
||||
}, storage_);
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return storage_.size();
|
||||
return std::visit([](const auto& x) { return x.size(); }, storage_);
|
||||
}
|
||||
|
||||
void toString(std::ostream&, bool upper = false, const IfcParse::entity* ent = nullptr) const;
|
||||
|
||||
Reference in New Issue
Block a user