Skip to content

Commit 59820cd

Browse files
committed
Migrate ObjectParser to simdjson On-Demand API
1 parent 2c372ab commit 59820cd

1 file changed

Lines changed: 43 additions & 29 deletions

File tree

cpp/src/arrow/json/object_parser.cc

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -29,34 +29,35 @@ class ObjectParser::Impl {
2929
// Copy into padded buffer
3030
padded_json_ = simdjson::padded_string(json);
3131

32-
// Parse
33-
auto result = parser_.parse(padded_json_);
34-
35-
// Handle parse errors
36-
if (result.error()) {
37-
return Status::Invalid("JSON parse error (code=", static_cast<int>(result.error()),
38-
")");
39-
}
40-
4132
// Store parsed document
42-
document_ = std::move(result).value();
33+
document_ = parser_.iterate(padded_json_);
4334

4435
// Validate root is an object
45-
if (!document_.is_object()) {
46-
return Status::TypeError("Not a JSON object");
36+
auto object = document_.get_object();
37+
if (object.error()) {
38+
if (object.error() == simdjson::INCORRECT_TYPE) {
39+
return Status::TypeError("Not a JSON object");
40+
}
41+
return Status::Invalid("JSON parse error: ",
42+
simdjson::error_message(object.error()));
4743
}
4844

4945
return Status::OK();
5046
}
5147

52-
Result<std::string> GetString(const char* key) const {
53-
auto field = document_[key];
48+
Result<std::string> GetString(const char* key) {
49+
document_.rewind();
50+
51+
auto object = document_.get_object();
52+
53+
auto field = object.find_field(key);
54+
5455
if (field.error() == simdjson::NO_SUCH_FIELD) {
5556
return Status::KeyError("Key '", key, "' does not exist");
5657
}
5758
if (field.error()) {
5859
return Status::Invalid("Error accessing key '", key,
59-
"': (code=", static_cast<int>(field.error()), ")");
60+
"': ", simdjson::error_message(field.error()));
6061
}
6162

6263
auto str_result = field.get_string();
@@ -65,23 +66,31 @@ class ObjectParser::Impl {
6566
}
6667
if (str_result.error()) {
6768
return Status::Invalid("Error getting string for key '", key,
68-
"': (code=", static_cast<int>(str_result.error()), ")");
69+
"': ", simdjson::error_message(str_result.error()));
6970
}
7071

7172
return std::string(str_result.value());
7273
}
7374

74-
Result<std::unordered_map<std::string, std::string>> GetStringMap() const {
75+
Result<std::unordered_map<std::string, std::string>> GetStringMap() {
7576
std::unordered_map<std::string, std::string> map;
7677

77-
auto obj_result = document_.get_object();
78-
if (obj_result.error()) {
79-
return Status::TypeError("Document is not an object");
80-
}
78+
document_.rewind();
79+
80+
auto object = document_.get_object();
8181

82-
simdjson::dom::object obj = obj_result.value();
82+
for (auto field : object) {
83+
auto key_result = field.unescaped_key();
84+
85+
auto key = key_result.value();
86+
87+
if (key_result.error()) {
88+
return Status::Invalid("Error getting value for key '", std::string(key),
89+
"': ", simdjson::error_message(key_result.error()));
90+
}
91+
92+
auto value = field.value();
8393

84-
for (auto [key, value] : obj) {
8594
auto str_result = value.get_string();
8695

8796
if (str_result.error() == simdjson::INCORRECT_TYPE) {
@@ -99,14 +108,19 @@ class ObjectParser::Impl {
99108
return map;
100109
}
101110

102-
Result<bool> GetBool(const char* key) const {
103-
auto field = document_[key];
111+
Result<bool> GetBool(const char* key) {
112+
document_.rewind();
113+
114+
auto object = document_.get_object();
115+
116+
auto field = object.find_field(key);
117+
104118
if (field.error() == simdjson::NO_SUCH_FIELD) {
105119
return Status::KeyError("Key '", key, "' does not exist");
106120
}
107121
if (field.error()) {
108122
return Status::Invalid("Error accessing key '", key,
109-
"': (code=", static_cast<int>(field.error()), ")");
123+
"': ", simdjson::error_message(field.error()));
110124
}
111125

112126
auto bool_result = field.get_bool();
@@ -115,16 +129,16 @@ class ObjectParser::Impl {
115129
}
116130
if (bool_result.error()) {
117131
return Status::Invalid("Error getting bool for key '", key,
118-
"': (code=", static_cast<int>(bool_result.error()), ")");
132+
"': ", simdjson::error_message(bool_result.error()));
119133
}
120134

121135
return bool_result.value();
122136
}
123137

124138
private:
125-
simdjson::dom::parser parser_;
139+
simdjson::ondemand::parser parser_;
126140
simdjson::padded_string padded_json_;
127-
simdjson::dom::element document_;
141+
simdjson::ondemand::document document_;
128142
};
129143

130144
ObjectParser::ObjectParser() : impl_(new ObjectParser::Impl()) {}

0 commit comments

Comments
 (0)