Skip to content

Commit

Permalink
Speed up for CBOR + BSON read operation
Browse files Browse the repository at this point in the history
  • Loading branch information
liuzicheng1987 committed Jun 3, 2024
1 parent 8086e14 commit 288d13a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 46 deletions.
45 changes: 12 additions & 33 deletions include/rfl/bson/Reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,16 @@ namespace bson {

/// Please refer to https://mongoc.org/libbson/current/api.html
struct Reader {
struct BSONValue {
bson_value_t val_;
};

struct BSONInputArray {
BSONValue* val_;
const bson_value_t* val_;
};

struct BSONInputObject {
BSONValue* val_;
const bson_value_t* val_;
};

struct BSONInputVar {
BSONValue* val_;
const bson_value_t* val_;
};

using InputArrayType = BSONInputArray;
Expand All @@ -55,7 +51,7 @@ struct Reader {
const std::string& _name, const InputObjectType& _obj) const noexcept {
bson_t b;
bson_iter_t iter;
const auto doc = _obj.val_->val_.value.v_doc;
const auto doc = _obj.val_->value.v_doc;
if (bson_init_static(&b, doc.data, doc.data_len)) {
if (bson_iter_init(&iter, &b)) {
while (bson_iter_next(&iter)) {
Expand All @@ -70,13 +66,13 @@ struct Reader {
}

bool is_empty(const InputVarType& _var) const noexcept {
return _var.val_->val_.value_type == BSON_TYPE_NULL;
return _var.val_->value_type == BSON_TYPE_NULL;
}

template <class T>
rfl::Result<T> to_basic_type(const InputVarType& _var) const noexcept {
const auto btype = _var.val_->val_.value_type;
const auto value = _var.val_->val_.value;
const auto btype = _var.val_->value_type;
const auto value = _var.val_->value;
if constexpr (std::is_same<std::remove_cvref_t<T>, std::string>()) {
switch (btype) {
case BSON_TYPE_UTF8:
Expand Down Expand Up @@ -126,7 +122,7 @@ struct Reader {

rfl::Result<InputArrayType> to_array(
const InputVarType& _var) const noexcept {
const auto btype = _var.val_->val_.value_type;
const auto btype = _var.val_->value_type;
if (btype != BSON_TYPE_ARRAY && btype != BSON_TYPE_DOCUMENT) {
return Error("Could not cast to an array.");
}
Expand All @@ -138,7 +134,7 @@ struct Reader {
const InputArrayType& _arr) const noexcept {
bson_t b;
bson_iter_t iter;
const auto doc = _arr.val_->val_.value.v_doc;
const auto doc = _arr.val_->value.v_doc;
if (bson_init_static(&b, doc.data, doc.data_len)) {
if (bson_iter_init(&iter, &b)) {
while (bson_iter_next(&iter)) {
Expand All @@ -157,7 +153,7 @@ struct Reader {
const InputObjectType& _obj) const noexcept {
bson_t b;
bson_iter_t iter;
const auto doc = _obj.val_->val_.value.v_doc;
const auto doc = _obj.val_->value.v_doc;
if (bson_init_static(&b, doc.data, doc.data_len)) {
if (bson_iter_init(&iter, &b)) {
while (bson_iter_next(&iter)) {
Expand All @@ -171,7 +167,7 @@ struct Reader {

rfl::Result<InputObjectType> to_object(
const InputVarType& _var) const noexcept {
const auto btype = _var.val_->val_.value_type;
const auto btype = _var.val_->value_type;
if (btype != BSON_TYPE_DOCUMENT) {
return Error("Could not cast to a document.");
}
Expand All @@ -188,27 +184,10 @@ struct Reader {
}
}

private:
struct BSONValues {
std::vector<rfl::Box<BSONValue>> vec_;
~BSONValues() {
for (auto& v : vec_) {
bson_value_destroy(&(v->val_));
}
}
};

private:
InputVarType to_input_var(bson_iter_t* _iter) const noexcept {
values_->vec_.emplace_back(rfl::Box<BSONValue>::make());
auto* last_value = values_->vec_.back().get();
bson_value_copy(bson_iter_value(_iter), &last_value->val_);
return InputVarType{last_value};
return InputVarType{bson_iter_value(_iter)};
}

private:
/// Contains the values inside the object.
rfl::Ref<BSONValues> values_;
};

} // namespace bson
Expand Down
11 changes: 5 additions & 6 deletions include/rfl/bson/read.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,11 @@ Result<internal::wrap_in_rfl_array_t<T>> read(const InputVarType& _obj) {
/// Parses an BSON object using reflection.
template <class T, class... Ps>
auto read(const uint8_t* _bytes, const size_t _size) {
Reader::BSONValue value;
value.val_.value.v_doc.data_len = static_cast<uint32_t>(_size);
value.val_.value.v_doc.data = const_cast<uint8_t*>(_bytes);
value.val_.value_type = BSON_TYPE_DOCUMENT;
auto doc = InputVarType{&value};
return read<T, Ps...>(doc);
bson_value_t val;
val.value.v_doc.data_len = static_cast<uint32_t>(_size);
val.value.v_doc.data = const_cast<uint8_t*>(_bytes);
val.value_type = BSON_TYPE_DOCUMENT;
return read<T, Ps...>(Reader::InputVarType{&val});
}

/// Parses an BSON object using reflection.
Expand Down
8 changes: 1 addition & 7 deletions include/rfl/cbor/Reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,14 +243,8 @@ struct Reader {
}

InputVarType to_input_var(CborValue* _ptr) const noexcept {
values_->emplace_back(rfl::Box<CborValue>::make(*_ptr));
auto* last_value = values_->back().get();
return InputVarType{last_value};
return InputVarType{_ptr};
}

private:
/// Contains the values inside the object.
rfl::Box<std::vector<rfl::Box<CborValue>>> values_;
};

} // namespace cbor
Expand Down

0 comments on commit 288d13a

Please sign in to comment.