Ensure only leaf values can push the iterator
This commit is contained in:
parent
fb93109c2d
commit
6a855f528b
|
@ -19,11 +19,13 @@ simdjson_really_inline json_iterator &json_iterator::operator=(json_iterator &&o
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
simdjson_really_inline json_iterator::json_iterator(ondemand::parser *_parser) noexcept
|
simdjson_really_inline json_iterator::json_iterator(ondemand::parser *_parser) noexcept
|
||||||
: token_iterator(_parser->dom_parser.buf, _parser->dom_parser.structural_indexes.get()), parser{_parser}
|
: token_iterator(_parser->dom_parser.buf, _parser->dom_parser.structural_indexes.get()),
|
||||||
|
parser{_parser},
|
||||||
|
current_string_buf_loc{parser->string_buf.get()},
|
||||||
|
active_lease_depth{0}
|
||||||
{
|
{
|
||||||
// Release the string buf so it can be reused by the next document
|
// Release the string buf so it can be reused by the next document
|
||||||
logger::log_headers();
|
logger::log_headers();
|
||||||
current_string_buf_loc = parser->string_buf.get();
|
|
||||||
}
|
}
|
||||||
simdjson_really_inline json_iterator::~json_iterator() noexcept = default;
|
simdjson_really_inline json_iterator::~json_iterator() noexcept = default;
|
||||||
|
|
||||||
|
@ -261,7 +263,10 @@ simdjson_really_inline bool json_iterator::is_alive() const noexcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson_really_inline json_iterator_ref json_iterator::borrow() noexcept {
|
simdjson_really_inline json_iterator_ref json_iterator::borrow() noexcept {
|
||||||
return json_iterator_ref(this);
|
SIMDJSON_ASSUME(active_lease_depth == 0);
|
||||||
|
const uint32_t child_depth = 1;
|
||||||
|
active_lease_depth = child_depth;
|
||||||
|
return json_iterator_ref(this, child_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -269,48 +274,58 @@ simdjson_really_inline json_iterator_ref json_iterator::borrow() noexcept {
|
||||||
//
|
//
|
||||||
simdjson_really_inline json_iterator_ref::json_iterator_ref() noexcept = default;
|
simdjson_really_inline json_iterator_ref::json_iterator_ref() noexcept = default;
|
||||||
simdjson_really_inline json_iterator_ref::json_iterator_ref(json_iterator_ref &&other) noexcept
|
simdjson_really_inline json_iterator_ref::json_iterator_ref(json_iterator_ref &&other) noexcept
|
||||||
: iter{std::forward<json_iterator_ref>(other).iter}
|
: iter{std::exchange(other.iter, nullptr)},
|
||||||
|
lease_depth{other.lease_depth}
|
||||||
{
|
{
|
||||||
other.iter = nullptr;
|
|
||||||
}
|
}
|
||||||
simdjson_really_inline json_iterator_ref &json_iterator_ref::operator=(json_iterator_ref &&other) noexcept {
|
simdjson_really_inline json_iterator_ref &json_iterator_ref::operator=(json_iterator_ref &&other) noexcept {
|
||||||
iter = std::forward<json_iterator_ref>(other).iter;
|
SIMDJSON_ASSUME(!is_active());
|
||||||
other.iter = nullptr;
|
iter = std::exchange(other.iter, nullptr);
|
||||||
|
lease_depth = other.lease_depth;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
simdjson_really_inline json_iterator_ref::json_iterator_ref(json_iterator *_iter) noexcept
|
simdjson_really_inline json_iterator_ref::json_iterator_ref(json_iterator *_iter, uint32_t _lease_depth) noexcept
|
||||||
: iter{_iter}
|
: iter{_iter},
|
||||||
|
lease_depth{_lease_depth}
|
||||||
{
|
{
|
||||||
|
SIMDJSON_ASSUME(is_active());
|
||||||
}
|
}
|
||||||
simdjson_really_inline json_iterator_ref::~json_iterator_ref() noexcept {
|
simdjson_really_inline json_iterator_ref::~json_iterator_ref() noexcept {
|
||||||
// The caller MUST consume their value and release the iterator before they die
|
// The caller MUST consume their value and release the iterator before they die
|
||||||
SIMDJSON_ASSUME(!iter);
|
SIMDJSON_ASSUME(!is_alive());
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson_really_inline json_iterator_ref json_iterator_ref::borrow() noexcept {
|
simdjson_really_inline json_iterator_ref json_iterator_ref::borrow() noexcept {
|
||||||
return json_iterator_ref(iter);
|
SIMDJSON_ASSUME(is_active());
|
||||||
|
const uint32_t child_depth = lease_depth + 1;
|
||||||
|
iter->active_lease_depth = child_depth;
|
||||||
|
return json_iterator_ref(iter, child_depth);
|
||||||
}
|
}
|
||||||
simdjson_really_inline void json_iterator_ref::release() noexcept {
|
simdjson_really_inline void json_iterator_ref::release() noexcept {
|
||||||
SIMDJSON_ASSUME(is_alive());
|
SIMDJSON_ASSUME(is_active());
|
||||||
|
iter->active_lease_depth = lease_depth - 1;
|
||||||
iter = nullptr;
|
iter = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson_really_inline json_iterator *json_iterator_ref::operator->() noexcept {
|
simdjson_really_inline json_iterator *json_iterator_ref::operator->() noexcept {
|
||||||
SIMDJSON_ASSUME(is_alive());
|
SIMDJSON_ASSUME(is_active());
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
simdjson_really_inline json_iterator &json_iterator_ref::operator*() noexcept {
|
simdjson_really_inline json_iterator &json_iterator_ref::operator*() noexcept {
|
||||||
SIMDJSON_ASSUME(is_alive());
|
SIMDJSON_ASSUME(is_active());
|
||||||
return *iter;
|
return *iter;
|
||||||
}
|
}
|
||||||
simdjson_really_inline const json_iterator &json_iterator_ref::operator*() const noexcept {
|
simdjson_really_inline const json_iterator &json_iterator_ref::operator*() const noexcept {
|
||||||
SIMDJSON_ASSUME(is_alive());
|
SIMDJSON_ASSUME(is_active());
|
||||||
return *iter;
|
return *iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson_really_inline bool json_iterator_ref::is_alive() const noexcept {
|
simdjson_really_inline bool json_iterator_ref::is_alive() const noexcept {
|
||||||
return iter != nullptr;
|
return iter != nullptr;
|
||||||
}
|
}
|
||||||
|
simdjson_really_inline bool json_iterator_ref::is_active() const noexcept {
|
||||||
|
return is_alive() && lease_depth == iter->active_lease_depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace ondemand
|
} // namespace ondemand
|
||||||
|
|
|
@ -137,6 +137,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
ondemand::parser *parser{};
|
ondemand::parser *parser{};
|
||||||
uint8_t *current_string_buf_loc{};
|
uint8_t *current_string_buf_loc{};
|
||||||
|
uint32_t active_lease_depth{};
|
||||||
|
|
||||||
simdjson_really_inline json_iterator(ondemand::parser *parser) noexcept;
|
simdjson_really_inline json_iterator(ondemand::parser *parser) noexcept;
|
||||||
template<int N>
|
template<int N>
|
||||||
|
@ -150,6 +151,7 @@ protected:
|
||||||
friend class value;
|
friend class value;
|
||||||
friend class raw_json_string;
|
friend class raw_json_string;
|
||||||
friend class parser;
|
friend class parser;
|
||||||
|
friend class json_iterator_ref;
|
||||||
friend simdjson_really_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta) noexcept;
|
friend simdjson_really_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta) noexcept;
|
||||||
}; // json_iterator
|
}; // json_iterator
|
||||||
|
|
||||||
|
@ -170,10 +172,12 @@ public:
|
||||||
simdjson_really_inline const json_iterator &operator*() const noexcept;
|
simdjson_really_inline const json_iterator &operator*() const noexcept;
|
||||||
|
|
||||||
simdjson_really_inline bool is_alive() const noexcept;
|
simdjson_really_inline bool is_alive() const noexcept;
|
||||||
|
simdjson_really_inline bool is_active() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
simdjson_really_inline json_iterator_ref(json_iterator *iter) noexcept;
|
simdjson_really_inline json_iterator_ref(json_iterator *iter, uint32_t lease_depth) noexcept;
|
||||||
json_iterator *iter;
|
json_iterator *iter{};
|
||||||
|
uint32_t lease_depth{};
|
||||||
|
|
||||||
friend class json_iterator;
|
friend class json_iterator;
|
||||||
}; // class json_iterator_ref
|
}; // class json_iterator_ref
|
||||||
|
|
Loading…
Reference in New Issue