Skip to content

Commit debe62a

Browse files
committed
Faster, non-validating skip() algorithm
1 parent 1b60172 commit debe62a

File tree

7 files changed

+56
-50
lines changed

7 files changed

+56
-50
lines changed

include/simdjson/internal/json_iterator.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ class json_iterator {
1111
really_inline json_iterator(const uint32_t *_structural_index, const uint8_t *_buf, uint8_t *_string_buf)
1212
: structural_index{_structural_index}, buf{_buf}, string_buf{_string_buf} {}
1313
json_iterator() = delete;
14-
really_inline const uint8_t * advance() noexcept { printf("advance(%c)\n", buf[*structural_index]); return &buf[*(structural_index++)]; }
15-
really_inline const uint8_t * get() const noexcept { printf("get(%c)\n", buf[*structural_index]); return &buf[*structural_index]; }
14+
really_inline const uint8_t * advance() noexcept { printf("advance %c (%u)\n", buf[*structural_index], *structural_index); return &buf[*(structural_index++)]; }
15+
really_inline const uint8_t * get() const noexcept { printf("get %c (%u)\n", buf[*structural_index], *structural_index); return &buf[*structural_index]; }
1616
really_inline const uint8_t * peek_prev() const noexcept { return &buf[*(structural_index-1)]; }
1717
really_inline const uint8_t * peek_next() const noexcept { return &buf[*(structural_index+1)]; }
1818

include/simdjson/stream/array.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class array {
4141
really_inline array(internal::json_iterator &json) noexcept;
4242
internal::json_iterator &json;
4343
friend class element;
44+
friend class document;
4445
friend class simdjson_result<array>;
4546
friend class simdjson_result<element>;
4647
friend class simdjson_result<document>;

include/simdjson/stream/document-inl.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ inline error_code document::skip() noexcept {
4848
really_inline document::operator array() noexcept(false) {
4949
return element(json);
5050
}
51-
really_inline document::operator object() noexcept(false ){
51+
really_inline document::operator object() noexcept(false) {
5252
return element(json);
5353
}
5454
really_inline document::operator raw_json_string() noexcept(false) {
@@ -70,10 +70,10 @@ really_inline document::operator int64_t() noexcept(false) {
7070
// return element(json);
7171
// }
7272

73-
inline array::iterator document::begin() noexcept(false) {
73+
really_inline array::iterator document::begin() noexcept(false) {
7474
return get_array().begin();
7575
}
76-
inline array::iterator document::end() noexcept(false) {
76+
really_inline array::iterator document::end() noexcept(false) {
7777
return get_array().end();
7878
}
7979
#endif // SIMDJSON_EXCEPTIONS
@@ -88,11 +88,11 @@ really_inline simdjson_result<stream::document>::simdjson_result(stream::documen
8888
really_inline simdjson_result<stream::document>::simdjson_result(stream::document &&value, error_code error) noexcept
8989
: internal::simdjson_result_base<stream::document>(std::forward<stream::document>(value), error) {}
9090

91-
really_inline simdjson_result<stream::array> simdjson_result<stream::document>::get_array() noexcept {
91+
really_inline simdjson_result<stream::array> simdjson_result<stream::document>::get_array() & noexcept {
9292
if (error()) { return { first.json, error() }; }
9393
return first.get_array();
9494
}
95-
really_inline simdjson_result<stream::object> simdjson_result<stream::document>::get_object() noexcept {
95+
really_inline simdjson_result<stream::object> simdjson_result<stream::document>::get_object() & noexcept {
9696
if (error()) { return { first.json, error() }; }
9797
return first.get_object();
9898
}
@@ -147,10 +147,10 @@ really_inline simdjson_result<stream::document>::operator int64_t() noexcept(fal
147147
// return get_bool();
148148
// }
149149

150-
inline stream::array::iterator simdjson_result<stream::document>::begin() noexcept(false) {
150+
really_inline stream::array::iterator simdjson_result<stream::document>::begin() & noexcept(false) {
151151
return get_array().begin();
152152
}
153-
inline stream::array::iterator simdjson_result<stream::document>::end() noexcept(false) {
153+
really_inline stream::array::iterator simdjson_result<stream::document>::end() & noexcept(false) {
154154
return get_array().end();
155155
}
156156
#endif // SIMDJSON_EXCEPTIONS

include/simdjson/stream/document.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,10 @@ class document {
3838
really_inline operator int64_t() noexcept(false);
3939
// really_inline operator bool() noexcept(false);
4040

41-
inline array::iterator begin() noexcept(false);
42-
inline array::iterator end() noexcept(false);
41+
really_inline array::iterator begin() noexcept(false);
42+
really_inline array::iterator end() noexcept(false);
4343
#endif // SIMDJSON_EXCEPTIONS
4444

45-
4645
protected:
4746
really_inline document(const dom::parser &parser, const uint8_t *buf) noexcept;
4847

@@ -61,17 +60,15 @@ struct simdjson_result<stream::document> : public internal::simdjson_result_base
6160
really_inline simdjson_result(stream::document &&value) noexcept; ///< @private
6261
really_inline simdjson_result(stream::document &&value, error_code error) noexcept; ///< @private
6362

64-
really_inline simdjson_result<stream::array> get_array() noexcept;
65-
really_inline simdjson_result<stream::object> get_object() noexcept;
63+
really_inline simdjson_result<stream::array> get_array() & noexcept;
64+
really_inline simdjson_result<stream::object> get_object() & noexcept;
6665
really_inline simdjson_result<stream::raw_json_string> get_raw_json_string() noexcept;
6766
// really_inline simdjson_result<std::string_view> get_string() noexcept;
6867
// really_inline simdjson_result<double> get_double() noexcept;
6968
really_inline simdjson_result<uint64_t> get_uint64() noexcept;
7069
really_inline simdjson_result<int64_t> get_int64() noexcept;
7170
// really_inline simdjson_result<bool> get_bool() noexcept;
7271

73-
WARN_UNUSED inline error_code skip() noexcept;
74-
7572
#if SIMDJSON_EXCEPTIONS
7673
really_inline operator stream::array() noexcept(false);
7774
really_inline operator stream::object() noexcept(false);
@@ -82,8 +79,8 @@ struct simdjson_result<stream::document> : public internal::simdjson_result_base
8279
really_inline operator int64_t() noexcept(false);
8380
// really_inline operator bool() noexcept(false);
8481

85-
inline stream::array::iterator begin() noexcept(false);
86-
inline stream::array::iterator end() noexcept(false);
82+
really_inline stream::array::iterator begin() & noexcept(false);
83+
really_inline stream::array::iterator end() & noexcept(false);
8784
#endif // SIMDJSON_EXCEPTIONS
8885
};
8986

include/simdjson/stream/element-inl.h

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ really_inline element::element(internal::json_iterator &_json) noexcept
1717
}
1818

1919
really_inline simdjson_result<array> element::get_array() noexcept {
20+
printf("start array\n");
2021
if (*json.advance() != '[') { return { json, INCORRECT_TYPE }; }
2122
return array(json);
2223
}
@@ -79,30 +80,37 @@ inline array::iterator element::end() noexcept(false) {
7980

8081
#endif // SIMDJSON_EXCEPTIONS
8182

82-
// TODO users should never have to call this for things to work. Figure out how to make it happen
83-
// in destructors or some other automatic mechanism.
84-
WARN_UNUSED inline error_code element::skip() noexcept {
83+
WARN_UNUSED really_inline error_code element::skip() noexcept {
84+
printf("skip()\n");
85+
// Skip a matching number of open and close braces. We don't validate *anything* inside them;
86+
// nor do we validate that they match each other. We only validate elements you actually use.
8587
switch (*json.advance()) {
86-
case '[':
87-
printf("skip [\n");
88-
for (auto [elem, error] : array(json)) {
89-
if (error) { return error; }
90-
error = elem.skip();
91-
if (error) { return error; }
92-
}
93-
break;
94-
case '{':
95-
printf("skip {\n");
96-
for (auto [field, error] : object(json)) {
97-
printf("field\n");
98-
if (error) { return error; }
99-
error = field.skip();
100-
if (error) { return error; }
101-
}
102-
break;
103-
default:
104-
break;
88+
case '[':
89+
case '{':
90+
break;
91+
case ']':
92+
case '}':
93+
return TAPE_ERROR;
94+
default:
95+
return SUCCESS;
10596
}
97+
// It's an array or hash. Count brackets until we are back to current depth.
98+
int depth = 1;
99+
do {
100+
printf("skip depth %d\n", depth);
101+
switch (*json.advance()) {
102+
case '[':
103+
case '{':
104+
depth++;
105+
break;
106+
case ']':
107+
case '}':
108+
depth--;
109+
break;
110+
default:
111+
break;
112+
}
113+
} while (depth > 0);
106114
return SUCCESS;
107115
}
108116

@@ -175,15 +183,15 @@ really_inline simdjson_result<stream::element>::operator int64_t() noexcept(fals
175183
// return get_bool();
176184
// }
177185

178-
inline stream::array::iterator simdjson_result<stream::element>::begin() noexcept(false) {
186+
really_inline stream::array::iterator simdjson_result<stream::element>::begin() noexcept(false) {
179187
return get_array().begin();
180188
}
181-
inline stream::array::iterator simdjson_result<stream::element>::end() noexcept(false) {
189+
really_inline stream::array::iterator simdjson_result<stream::element>::end() noexcept(false) {
182190
return get_array().end();
183191
}
184192
#endif // SIMDJSON_EXCEPTIONS
185193

186-
WARN_UNUSED inline error_code simdjson_result<stream::element>::skip() noexcept {
194+
WARN_UNUSED really_inline error_code simdjson_result<stream::element>::skip() noexcept {
187195
if (error()) { return error(); }
188196
return first.skip();
189197
}

include/simdjson/stream/element.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ class element {
3333
really_inline operator int64_t() noexcept(false);
3434
// really_inline operator bool() noexcept(false);
3535

36-
inline array::iterator begin() noexcept(false);
37-
inline array::iterator end() noexcept(false);
36+
really_inline array::iterator begin() noexcept(false);
37+
really_inline array::iterator end() noexcept(false);
3838
#endif // SIMDJSON_EXCEPTIONS
3939

4040
// TODO users should never have to call this for things to work. Figure out how to make it happen
4141
// in destructors or some other automatic mechanism.
42-
WARN_UNUSED inline error_code skip() noexcept;
42+
WARN_UNUSED really_inline error_code skip() noexcept;
4343

4444
protected:
4545
really_inline element(internal::json_iterator &_json) noexcept;
@@ -71,7 +71,7 @@ struct simdjson_result<stream::element> : public internal::simdjson_result_base<
7171
really_inline simdjson_result<int64_t> get_int64() noexcept;
7272
// really_inline simdjson_result<bool> get_bool() noexcept;
7373

74-
WARN_UNUSED inline error_code skip() noexcept;
74+
WARN_UNUSED really_inline error_code skip() noexcept;
7575

7676
#if SIMDJSON_EXCEPTIONS
7777
really_inline operator stream::array() noexcept(false);
@@ -83,8 +83,8 @@ struct simdjson_result<stream::element> : public internal::simdjson_result_base<
8383
really_inline operator int64_t() noexcept(false);
8484
// really_inline operator bool() noexcept(false);
8585

86-
inline stream::array::iterator begin() noexcept(false);
87-
inline stream::array::iterator end() noexcept(false);
86+
really_inline stream::array::iterator begin() noexcept(false);
87+
really_inline stream::array::iterator end() noexcept(false);
8888
#endif // SIMDJSON_EXCEPTIONS
8989
};
9090

tests/basictests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ namespace stream_tests {
393393

394394
// Parse and iterate through each car
395395
int count = 0;
396-
for (stream::element car : parser.stream(cars_json).get_array()) {
396+
for (stream::element car : parser.stream(cars_json)) {
397397
error_code error = car.skip();
398398
if (error) { std::cerr << "Error: " << error << std::endl; return false; }
399399
count++;

0 commit comments

Comments
 (0)