mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 02:47:48 +00:00
Ugly conditional compilation for without rdb support
This commit is contained in:
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user