Skip to content

Commit bbbc06f

Browse files
authored
GH-51037: [C++] Replace RapidJSON with simdjson in JSON parser (#51038)
### Rationale for this change This PR continues the simdjson migration by replacing the RapidJSON-based parsing implementation used by the JSON parser. The existing parser uses RapidJSON's SAX/handler interface to parse JSON values and populate Arrow builders. This change replaces that implementation with simdjson's ondemand API while retaining the existing builder and type-inference logic. ### Changes * Replace the RapidJSON parser and handler interface with simdjson's ondemand API. * Parse JSON documents using `simdjson::ondemand::parser::iterate_many`. * Use `ResolveSimdjsonResult()` consistently when handling simdjson results. * Preserve support for nested objects and arrays. * Preserve explicit-schema and inferred-field behavior. * Preserve unexpected-field handling for `Error`, `Ignore`, and `InferType`. * Continue storing numeric values as raw JSON tokens. * Trim trailing whitespace from numeric raw tokens to preserve existing behavior. * Preserve JSON parse error propagation through `Status::Invalid`. * Remove the parser's RapidJSON-specific dependencies. ### Are there any user-facing changes? No ### Was AI used for this PR? In accordance to the [AI generation guidelines](https://arrow.apache.org/docs/dev/developers/overview.html#ai-generated-code), please disclose below whether and how AI was used in this PR. **PR code and description written by:** - [X] Human - [X] AI **Reviewed before submission by:** - [X] Human - [X] AI - [ ] Not reviewed Fixes: #51037 * GitHub Issue: #51037 Authored-by: Aaditya Srinivasan <aadityasri03@gmail.com> Signed-off-by: Antoine Pitrou <antoine@python.org>
1 parent 1afe206 commit bbbc06f

8 files changed

Lines changed: 346 additions & 413 deletions

File tree

‎cpp/cmake_modules/ThirdpartyToolchain.cmake‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2869,6 +2869,10 @@ function(build_simdjson)
28692869

28702870
prepare_fetchcontent()
28712871

2872+
# Keep simdjson's threading configuration consistent with Arrow's,
2873+
# which is required for Emscripten where Arrow threading is disabled.
2874+
set(SIMDJSON_ENABLE_THREADS ${ARROW_ENABLE_THREADING})
2875+
28722876
# simdjson enables precompiled headers unconditionally.
28732877
# Recompiling simdjson.cpp against it produces differing artifacts
28742878
# Disable precompiled headers to avoid reproducible build failures.

‎cpp/src/arrow/json/chunker.cc‎

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,6 @@ namespace arrow {
3232
namespace json {
3333
namespace {
3434

35-
// XXX We could try to SIMD-accelerate this routine but it's called only
36-
// once per chunk and also will presumably examine a minimal amount of bytes.
37-
int64_t ConsumeWhitespace(std::string_view view) {
38-
const auto ws_count = view.find_first_not_of(" \t\r\n");
39-
if (ws_count == std::string_view::npos) {
40-
return view.size();
41-
}
42-
return static_cast<int64_t>(ws_count);
43-
}
44-
4535
// A BoundaryFinder implementation that assumes JSON objects can contain raw newlines,
4636
// and uses the structural indexes computed by simdjson to delimit them.
4737
class ParsingBoundaryFinder : public BoundaryFinder {
@@ -156,7 +146,8 @@ class ParsingBoundaryFinder : public BoundaryFinder {
156146
if (consumed_length > 0) {
157147
// If we found at least one document, also consume its trailing whitespace
158148
// to avoid stray bytes at the end of the stream.
159-
consumed_length += ConsumeWhitespace(input.substr(consumed_length));
149+
consumed_length += internal::ConsumeJsonWhitespace(input.substr(consumed_length),
150+
/*trailing=*/false);
160151
}
161152
return consumed_length;
162153
}

0 commit comments

Comments
 (0)