Exploration of using rocksdb as file+instance storage

This commit is contained in:
Thomas Krijnen
2025-02-21 16:12:16 +01:00
parent cdcbc2ad3b
commit da4e86a1d5
16 changed files with 2012 additions and 547 deletions
+136 -18
View File
@@ -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;