Ugly conditional compilation for without rdb support

This commit is contained in:
Thomas Krijnen
2025-08-26 13:56:03 +02:00
parent 6095c523d7
commit 96336d6f68
8 changed files with 157 additions and 17 deletions
+29 -9
View File
@@ -35,7 +35,9 @@ namespace {
{
if (storage_model_ == 0) {
return array_.storage_ptr->get<T>(index_);
} else {
}
#ifdef WITH_ROCKSDB
else {
T val;
if constexpr (
// the following types cannot be directly deserialized from rocksdb, but need to be constructed
@@ -48,6 +50,7 @@ namespace {
}
return val;
}
#endif
}
template<typename T>
@@ -55,7 +58,9 @@ namespace {
{
if (storage_model_ == 0) {
return array_.storage_ptr->has<T>(index_);
} else {
}
#ifdef WITH_ROCKSDB
else {
std::string str;
array_.db_ptr->db->Get(rocksdb::ReadOptions{}, (is_entity ? "i|" : "t|") + std::to_string(instance_name_) + "|" + std::to_string(index_), &str);
if constexpr (std::is_same_v<T, Blank>) {
@@ -65,21 +70,24 @@ namespace {
}
return str[0] == TypeEncoder::encode_type<T>();
}
#endif
}
inline size_t dispatch_index_(AttributeValue::pointer_type array_, uint8_t storage_model_, size_t instance_name_, bool is_entity, uint8_t index_)
{
if (storage_model_ == 0) {
return array_.storage_ptr->index(index_);
} else {
}
#ifdef WITH_ROCKSDB
else {
std::string str;
if (!array_.db_ptr->db->Get(rocksdb::ReadOptions{}, (is_entity ? "i|" : "t|") + std::to_string(instance_name_) + "|" + std::to_string(index_), &str).ok()) {
return TypeEncoder::encode_type<Blank>() - 'A';
}
return (size_t) str[0] - 'A';
}
#endif
}
}
AttributeValue::operator int() const
@@ -112,7 +120,9 @@ AttributeValue::operator std::string() const
// @todo also we don't really need to store a reference to the enumeration type, when this same type is already stored on the definition of the entity and no other value can be provided.
if (storage_model_ == 0) {
return dispatch_get_<EnumerationReference>(array_, storage_model_, instance_name_, entity_or_type_ == 1 ? true : false, index_).value();
} else {
}
#ifdef WITH_ROCKSDB
else {
std::string str;
array_.db_ptr->db->Get(rocksdb::ReadOptions{}, (entity_or_type_ == 1 ? "i|" : "t|") + std::to_string(instance_name_) + "|" + std::to_string(index_), &str);
size_t v;
@@ -121,6 +131,7 @@ AttributeValue::operator std::string() const
memcpy(&v, str.data() + 1 + sizeof(size_t), sizeof(size_t));
return decl->lookup_enum_value(v);
}
#endif
}
return dispatch_get_<std::string>(array_, storage_model_, instance_name_, entity_or_type_ == 1 ? true : false, index_);
}
@@ -129,7 +140,9 @@ AttributeValue::operator EnumerationReference() const
{
if (storage_model_ == 0) {
return dispatch_get_<EnumerationReference>(array_, storage_model_, instance_name_, entity_or_type_ == 1 ? true : false, index_);
} else {
}
#ifdef WITH_ROCKSDB
else {
std::string str;
array_.db_ptr->db->Get(rocksdb::ReadOptions{}, (entity_or_type_ == 1 ? "i|" : "t|") + std::to_string(instance_name_) + "|" + std::to_string(index_), &str);
size_t v;
@@ -138,6 +151,7 @@ AttributeValue::operator EnumerationReference() const
memcpy(&v, str.data() + 1 + sizeof(size_t), sizeof(size_t));
return EnumerationReference(decl, v);
}
#endif
}
AttributeValue::operator boost::dynamic_bitset<>() const
@@ -149,7 +163,9 @@ AttributeValue::operator IfcUtil::IfcBaseClass* () const
{
if (storage_model_ == 0) {
return dispatch_get_<IfcUtil::IfcBaseClass*>(array_, storage_model_, instance_name_, entity_or_type_ == 1 ? true : false, index_);
} else {
}
#ifdef WITH_ROCKSDB
else {
std::string str;
array_.db_ptr->db->Get(rocksdb::ReadOptions{}, (entity_or_type_ == 1 ? "i|" : "t|") + std::to_string(instance_name_) + "|" + std::to_string(index_), &str);
size_t v;
@@ -160,9 +176,9 @@ AttributeValue::operator IfcUtil::IfcBaseClass* () const
} else if (str[1] == 't') {
// type reference by Identity
return array_.db_ptr->assert_existance(v, IfcParse::impl::rocks_db_file_storage::typedecl_ref);
}
}
}
#endif
}
AttributeValue::operator std::vector<int>() const
@@ -221,6 +237,8 @@ IfcUtil::ArgumentType AttributeValue::type() const
return static_cast<IfcUtil::ArgumentType>(dispatch_index_(array_, storage_model_, instance_name_, entity_or_type_ == 1 ? true : false, index_));
}
#ifdef WITH_ROCKSDB
bool impl::serialize(std::string& val, const IfcUtil::IfcBaseClass* t)
{
auto s = sizeof(size_t);
@@ -432,3 +450,5 @@ template bool rocks_db_attribute_storage::has<aggregate_of_aggregate_of_instance
template bool rocks_db_attribute_storage::has<Derived>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<empty_aggregate_t>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<empty_aggregate_of_aggregate_t>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
#endif
+21 -3
View File
@@ -25,6 +25,8 @@
#include "aggregate_of_instance.h"
#include "IfcSchema.h"
#ifdef WITH_ROCKSDB
#pragma push_macro("Handle")
#undef Handle
@@ -32,6 +34,8 @@
#pragma pop_macro("Handle")
#endif
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/logic/tribool.hpp>
@@ -161,6 +165,7 @@ namespace IfcParse {
}
}
#if WITH_ROCKSDB
namespace impl {
@@ -275,6 +280,7 @@ namespace impl {
bool deserialize(IfcParse::impl::rocks_db_file_storage*, const std::string& val, aggregate_of_aggregate_of_instance::ptr& t);
}
#endif
// short lived
struct AttributeValue {
@@ -384,8 +390,10 @@ struct AttributeValue {
}
};
struct rocks_db_attribute_storage {
public:
#ifdef WITH_ROCKSDB
// @todo void* is obviously very ugly here
template<typename T>
void set(void* storage, const IfcParse::declaration*, std::size_t identity, std::size_t index, const T& value);
@@ -398,6 +406,7 @@ public:
// @todo do we need visitation on all data/storage/attribute levels?
AttributeValue((IfcParse::impl::rocks_db_file_storage*)storage, identity, decl->as_entity() ? 1 : 0, index).apply_visitor(std::forward<Visitor>(visitor));
}
#endif
};
class IFC_PARSE_API IfcEntityInstanceData {
@@ -439,27 +448,36 @@ class IFC_PARSE_API IfcEntityInstanceData {
void set_attribute_value(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index, T&& value) {
if (storage_) {
storage_->set(index, value);
} else {
}
#ifdef WITH_ROCKSDB
else {
rocks_db_attribute_storage{}.set(storage, decl, identity, index, value);
}
#endif
}
template<typename T>
bool has_attribute_value(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index) const {
if (storage_) {
return storage_->has<T>(index);
} else {
}
#ifdef WITH_ROCKSDB
else {
return rocks_db_attribute_storage{}.has<T>(storage, decl, identity, index);
}
#endif
}
template<typename Visitor>
auto apply_visitor(void* storage, const IfcParse::declaration* decl, std::size_t identity, Visitor&& visitor, std::size_t index) const {
if (storage_) {
return storage_->apply_visitor(std::forward<Visitor>(visitor), index);
} else {
}
#ifdef WITH_ROCKSDB
else {
return rocks_db_attribute_storage{}.apply_visitor(storage, decl, identity, index, std::forward<Visitor>(visitor));
}
#endif
}
void toString(void* storage, const IfcParse::declaration*, std::size_t identity, std::ostream&, bool upper = false) const;
+11 -1
View File
@@ -344,6 +344,7 @@ 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) {
#ifdef WITH_ROCKSDB
if (r == IfcParse::impl::rocks_db_file_storage::entityinstance_ref) {
auto it = instance_cache_.find(number);
if (it != instance_cache_.end()) {
@@ -388,11 +389,15 @@ IfcUtil::IfcBaseClass* IfcParse::impl::rocks_db_file_storage::assert_existance(s
} else {
throw IfcException("Instance #" + boost::lexical_cast<std::string>(number) + " not found");
}
#else
throw IfcException("RocksDB support not compiled in");
#endif
}
namespace {
rocksdb::DB* init_db(const std::string& filepath) {
rocksdb::DB* db;
rocksdb::DB* db = nullptr;
#ifdef WITH_ROCKSDB
rocksdb::Options options;
// options.disable_auto_compactions = true;
options.create_if_missing = true;
@@ -401,6 +406,7 @@ namespace {
if (!status.ok()) {
throw std::runtime_error(status.ToString());
}
#endif // WITH_ROCKSDB#
return db;
}
}
@@ -423,6 +429,7 @@ IfcParse::impl::rocks_db_file_storage::rocks_db_file_storage(const std::string&
IfcParse::impl::rocks_db_file_storage::~rocks_db_file_storage()
{
#ifdef WITH_ROCKSDB
rocksdb::FlushOptions flush_options;
flush_options.allow_write_stall = true;
flush_options.wait = true; // Wait until flush completes.
@@ -435,6 +442,7 @@ IfcParse::impl::rocks_db_file_storage::~rocks_db_file_storage()
db->Close();
delete db;
#endif
}
@@ -447,6 +455,7 @@ IfcUtil::IfcBaseClass* IfcParse::impl::rocks_db_file_storage::instance_by_id(int
void IfcParse::impl::rocks_db_file_storage::process_deletion_inverse(IfcUtil::IfcBaseClass* inst)
{
#ifdef WITH_ROCKSDB
auto id = inst->id();
{
@@ -500,6 +509,7 @@ void IfcParse::impl::rocks_db_file_storage::process_deletion_inverse(IfcUtil::If
}
}
}
#endif
}
IfcUtil::IfcBaseClass* IfcParse::impl::in_memory_file_storage::instance_by_id(int id)
+3 -1
View File
@@ -35,7 +35,8 @@
#include <iterator>
#include <map>
#include "rocksdb/merge_operator.h"
#ifdef WITH_ROCKSDB
#include <rocksdb/merge_operator.h>
namespace {
// @todo move to a proper place
@@ -69,6 +70,7 @@ namespace {
}
};
}
#endif
namespace IfcParse {
+20 -3
View File
@@ -791,6 +791,7 @@ namespace {
}
void IfcParse::impl::rocks_db_file_storage::register_inverse(unsigned id_from, const IfcParse::entity* from_entity, int inst_id, int attribute_index) {
#ifdef WITH_ROCKSDB
static std::string s;
uint32_t v = id_from;
s.resize(sizeof(uint32_t));
@@ -808,9 +809,11 @@ void IfcParse::impl::rocks_db_file_storage::register_inverse(unsigned id_from, c
auto new_val = current + s;
db->Put(wopts, key, new_val);
}*/
#endif
}
void IfcParse::impl::rocks_db_file_storage::unregister_inverse(unsigned id_from, const IfcParse::entity* from_entity, IfcUtil::IfcBaseClass* inst, int attribute_index) {
#ifdef WITH_ROCKSDB
static std::string s;
auto inst_id = inst->id();
auto key = "v|" + to_string_fixed_width(inst_id, 10) + "|" + to_string_fixed_width(from_entity->index_in_schema(), 4) + "|" + to_string_fixed_width(attribute_index, 2);
@@ -827,10 +830,12 @@ void IfcParse::impl::rocks_db_file_storage::unregister_inverse(unsigned id_from,
memcpy(s.data(), vals.data(), s.size());
db->Put(wopts, key, s);
}
#endif
}
void IfcParse::impl::rocks_db_file_storage::add_type_ref(IfcUtil::IfcBaseClass* new_entity)
{
#ifdef WITH_ROCKSDB
size_t v;
std::string s(sizeof(size_t), ' ');
@@ -855,10 +860,12 @@ void IfcParse::impl::rocks_db_file_storage::add_type_ref(IfcUtil::IfcBaseClass*
v = new_entity->declaration().index_in_schema();
memcpy(s.data(), &v, sizeof(size_t));
db->Put(wopts, (new_entity->declaration().as_entity() ? "i|" : "t|") + std::to_string(new_entity->id() ? new_entity->id() : new_entity->identity()) + "|_", s);
#endif
}
void IfcParse::impl::rocks_db_file_storage::remove_type_ref(IfcUtil::IfcBaseClass* new_entity)
{
#ifdef WITH_ROCKSDB
if (new_entity->declaration().as_entity()) {
std::string s;
auto key = "t|" + std::to_string(new_entity->declaration().index_in_schema());
@@ -873,6 +880,7 @@ void IfcParse::impl::rocks_db_file_storage::remove_type_ref(IfcUtil::IfcBaseClas
}
db->Delete(wopts, (new_entity->declaration().as_entity() ? "i|" : "t|") + std::to_string(new_entity->id() ? new_entity->id() : new_entity->identity()) + "|_");
#endif
}
namespace {
@@ -2275,7 +2283,9 @@ aggregate_of_instance::ptr IfcFile::instances_by_reference(int t) {
ret->push(instance_by_id(i));
}
}
} else if constexpr (std::is_same_v<std::decay_t<decltype(x)>, impl::rocks_db_file_storage>) {
}
#ifdef WITH_ROCKSDB
else if constexpr (std::is_same_v<std::decay_t<decltype(x)>, impl::rocks_db_file_storage>) {
// @todo no lower/upper_bounds() implemented yet
auto prefix = "v|" + std::to_string(t) + "|";
auto it = x.db->NewIterator(rocksdb::ReadOptions());
@@ -2288,7 +2298,9 @@ aggregate_of_instance::ptr IfcFile::instances_by_reference(int t) {
}
it->Next();
}
} else {
}
#endif
else {
throw std::runtime_error("Storage not initialized");
}
}, storage_);
@@ -2482,7 +2494,9 @@ aggregate_of_instance::ptr IfcFile::getInverse(int instance_id, const IfcParse::
}
}
}
} else if constexpr (std::is_same_v<std::decay_t<decltype(x)>, impl::rocks_db_file_storage>) {
}
#ifdef WITH_ROCKSDB
else if constexpr (std::is_same_v<std::decay_t<decltype(x)>, impl::rocks_db_file_storage>) {
if (attribute_index == -1) {
// @todo no lower/upper_bounds() implemented yet
auto prefix = "v|" + std::to_string(instance_id) + "|" + std::to_string(ent->index_in_schema()) + "|";
@@ -2505,6 +2519,7 @@ aggregate_of_instance::ptr IfcFile::getInverse(int instance_id, const IfcParse::
}
}
}
#endif
}, storage_);
});
@@ -2717,6 +2732,7 @@ AttributeValue IfcEntityInstanceData::get_attribute_value(void* storage, const I
}
bool IfcParse::impl::rocks_db_file_storage::read_schema(const IfcParse::schema_definition*& schema) {
#ifdef WITH_ROCKSDB
std::string value;
auto key = "h|file_schema|0";
db->Get(rocksdb::ReadOptions{}, key, &value);
@@ -2725,6 +2741,7 @@ bool IfcParse::impl::rocks_db_file_storage::read_schema(const IfcParse::schema_d
schema = schema_by_name(strings[0]);
return true;
}
#endif
return false;
}
+30
View File
@@ -17,8 +17,14 @@
* *
********************************************************************************/
#ifndef ROCKSDB_MAP_ADAPTER_H
#define ROCKSDB_MAP_ADAPTER_H
#ifdef WITH_ROCKSDB
#include <rocksdb/db.h>
#include <rocksdb/options.h>
#endif
#include <memory>
#include <string>
#include <utility>
@@ -217,6 +223,7 @@ public:
iterator(const iterator& other)
: db_(other.db_), prefix_(other.prefix_), codec_(other.codec_)
{
#ifdef WITH_ROCKSDB
if (other.it_) {
std::string curr = other.it_->key().ToString();
it_.reset(db_->NewIterator(rocksdb::ReadOptions{}));
@@ -224,9 +231,11 @@ public:
if (!it_->Valid() || it_->key().ToString() != curr)
it_.reset();
}
#endif
}
iterator& operator=(const iterator& other) {
#ifdef WITH_ROCKSDB
if (this != &other) {
db_ = other.db_;
prefix_ = other.prefix_;
@@ -241,14 +250,19 @@ public:
it_.reset();
}
}
#endif
return *this;
}
value_type operator*() const {
#ifdef WITH_ROCKSDB
std::string full_key = it_->key().ToString();
std::string key_without_prefix = full_key.substr(prefix_.size());
std::string value_str = it_->value().ToString();
return { key_from_string<key_type>(key_without_prefix), codec_.decode(value_str) };
#else
return cached_value_;
#endif
}
// operator-> uses a mutable cache to return a pointer to the current value.
@@ -258,10 +272,12 @@ public:
}
iterator& operator++() {
#if WITH_ROCKSDB
if (it_) {
it_->Next();
check_valid();
}
#endif
return *this;
}
@@ -272,9 +288,11 @@ public:
}
bool operator==(const iterator& other) const {
#ifdef WITH_ROCKSDB
if (!it_ && !other.it_) return true;
if (it_ && other.it_)
return it_->key().ToString() == other.it_->key().ToString();
#endif
return false;
}
@@ -284,11 +302,13 @@ public:
};
iterator begin() const {
#ifdef WITH_ROCKSDB
auto iter = std::unique_ptr<rocksdb::Iterator>(db_->NewIterator(rocksdb::ReadOptions{}));
iter->Seek(prefix_);
if (iter->Valid() && iter->key().starts_with(prefix_)) {
return iterator(db_, prefix_, std::move(iter), codec_);
}
#endif
return end();
}
@@ -297,23 +317,30 @@ public:
}
iterator find(const key_type& key) const {
#ifdef WITH_ROCKSDB
std::string key_str = key_to_string(key);
std::string full_key = prefix_ + key_str;
auto iter = std::unique_ptr<rocksdb::Iterator>(db_->NewIterator(rocksdb::ReadOptions{}));
iter->Seek(full_key);
if (iter->Valid() && iter->key().ToString() == full_key)
return iterator(db_, prefix_, std::move(iter), codec_);
#endif
return end();
}
size_t erase(const key_type& key) {
#ifdef WITH_ROCKSDB
std::string key_str = key_to_string(key);
std::string full_key = prefix_ + key_str;
rocksdb::Status s = db_->Delete(rocksdb::WriteOptions{}, full_key);
return s.ok() ? 1 : 0;
#else
return 0;
#endif
}
std::pair<iterator, bool> insert(const value_type& val) {
#ifdef WITH_ROCKSDB
std::string key_str = key_to_string(val.first);
std::string full_key = prefix_ + key_str;
std::string existing;
@@ -327,6 +354,9 @@ public:
if (!s.ok()) {
return { end(), false };
}
#endif
return { find(val.first), true };
}
};
#endif
+24
View File
@@ -17,8 +17,14 @@
* *
********************************************************************************/
#ifndef ROCKSDB_SET_VIEW_H
#define ROCKSDB_SET_VIEW_H
#ifdef WITH_ROCKSDB
#include <rocksdb/db.h>
#include <rocksdb/options.h>
#endif
#include <memory>
#include <string>
#include <iterator>
@@ -60,11 +66,15 @@ public:
// Helper: extract the key (i.e. the value) from the current RocksDB key.
value_type extract_current_value() const {
#ifdef WITH_ROCKSDB
std::string full_key = it_->key().ToString();
std::string remainder = full_key.substr(prefix_.size());
size_t pos = remainder.find('|');
std::string key_str = (pos != std::string::npos) ? remainder.substr(0, pos) : remainder;
return key_from_string<key_type>(key_str);
#else
return cached_value_;
#endif
}
// Validates the current iterator state.
@@ -86,6 +96,7 @@ public:
iterator(const iterator& other)
: db_(other.db_), prefix_(other.prefix_)
{
#ifdef WITH_ROCKSDB
if (other.it_) {
std::string curr = other.it_->key().ToString();
it_.reset(db_->NewIterator(rocksdb::ReadOptions{}));
@@ -93,9 +104,11 @@ public:
if (!it_->Valid() || it_->key().ToString() != curr)
it_.reset();
}
#endif
}
iterator& operator=(const iterator& other) {
#ifdef WITH_ROCKSDB
if (this != &other) {
db_ = other.db_;
prefix_ = other.prefix_;
@@ -109,6 +122,7 @@ public:
it_.reset();
}
}
#endif
return *this;
}
@@ -125,6 +139,7 @@ public:
// Pre-increment: advance the iterator and skip over any duplicate keys.
iterator& operator++() {
#ifdef WITH_ROCKSDB
if (it_) {
// Record the current key value.
value_type curr = extract_current_value();
@@ -135,6 +150,7 @@ public:
if (!it_ || !it_->Valid() || !it_->key().starts_with(prefix_))
it_.reset();
}
#endif
return *this;
}
@@ -145,10 +161,12 @@ public:
}
bool operator==(const iterator& other) const {
#ifdef WITH_ROCKSDB
if (!it_ && !other.it_)
return true;
if (it_ && other.it_)
return it_->key().ToString() == other.it_->key().ToString();
#endif
return false;
}
@@ -159,10 +177,12 @@ public:
// Returns an iterator to the first element in the key-space (or end() if none exist).
iterator begin() const {
#ifdef WITH_ROCKSDB
auto iter = std::unique_ptr<rocksdb::Iterator>(db_->NewIterator(rocksdb::ReadOptions{}));
iter->Seek(prefix_);
if (iter->Valid() && iter->key().starts_with(prefix_))
return iterator(db_, prefix_, std::move(iter));
#endif
return end();
}
@@ -173,6 +193,7 @@ public:
// Read-only find: returns an iterator to the element with the given key if it exists.
iterator find(const key_type& key) const {
#ifdef WITH_ROCKSDB
std::string key_str = key_to_string(key);
// Construct the search key: prefix + key_str + separator.
std::string start_key = prefix_ + key_str + "|";
@@ -186,6 +207,7 @@ public:
if (key_from_string<key_type>(found_key_str) == key)
return iterator(db_, prefix_, std::move(iter));
}
#endif
return end();
}
@@ -193,3 +215,5 @@ public:
// @todo
}
};
#endif
+19
View File
@@ -1,6 +1,19 @@
#ifndef STORAGE_H
#define STORAGE_H
#ifndef WITH_ROCKSDB
namespace rocksdb {
class DB {};
class Options {};
class WriteOptions {};
class ReadOptions {};
class Iterator {};
class Status {};
}
#endif
#include "rocksdb_map_adapter.h"
#include "rocksdb_set_view.h"
#include "map_variant.h"
@@ -436,6 +449,7 @@ namespace IfcParse {
static constexpr char prefix_[] = "t|";
boost::optional<size_t> read_id_() const {
#ifdef WITH_ROCKSDB
auto sv = state_->key().ToStringView();
auto ii = sv.find("|", 2);
if (ii != decltype(sv)::npos) {
@@ -445,6 +459,7 @@ namespace IfcParse {
return (size_t)result;
}
}
#endif
return boost::none;
}
public:
@@ -464,15 +479,18 @@ namespace IfcParse {
rocksdb_types_iterator(const rocks_db_file_storage* fs)
: storage_(fs)
{
#ifdef WITH_ROCKSDB
state_ = fs->db->NewIterator(rocksdb::ReadOptions());
state_->Seek(prefix_);
if (!state_->Valid() || !state_->key().starts_with(prefix_)) {
delete state_;
state_ = nullptr;
}
#endif
}
rocksdb_types_iterator& operator++() {
#ifdef WITH_ROCKSDB
if (!state_) {
return *this;
}
@@ -490,6 +508,7 @@ namespace IfcParse {
}
}
return *this;
#endif
}
rocksdb_types_iterator operator++(int) {