This is an automated email from the ASF dual-hosted git repository.
pitrou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new 3deec0b119 GH-50690: [C++] Migrate ObjectWriter users to JsonWriter
(#50691)
3deec0b119 is described below
commit 3deec0b119a3fc009e86e473242a6b647eea94e8
Author: Aaditya Srinivasan <[email protected]>
AuthorDate: Wed Jul 29 15:05:45 2026 +0530
GH-50690: [C++] Migrate ObjectWriter users to JsonWriter (#50691)
### Rationale for this change
This PR continues the simdjson migration by replacing the remaining
`ObjectWriter` users with `JsonWriter`. With all usages migrated, the obsolete
`ObjectWriter` implementation and its associated build configuration are
removed.
### What changes are included in this PR?
* Replace `ObjectWriter` with `JsonWriter` in:
* `key_material.cc`
* `key_metadata.cc`
* `local_wrap_kms_client.cc`
* `file_system_key_material_store.cc`
* Remove the unused `ObjectWriter` implementation (`object_writer.cc` and
`object_writer.h`).
* Remove `object_writer.h` from the installed headers.
* Update the Arrow build configuration to stop building `object_writer.cc`.
* Link Parquet against `simdjson::simdjson` since it now includes
`json_writer_internal.h`.
### Are these changes tested?
Yes.
### Are there any user-facing changes?
No.
Closes: #50690
* GitHub Issue: #50690
Lead-authored-by: Aaditya Srinivasan <[email protected]>
Co-authored-by: Antoine Pitrou <[email protected]>
Signed-off-by: Antoine Pitrou <[email protected]>
---
cpp/src/arrow/CMakeLists.txt | 1 -
cpp/src/arrow/json/json_writer_internal.cc | 10 +++
cpp/src/arrow/json/json_writer_internal.h | 3 +
cpp/src/arrow/json/meson.build | 3 +-
cpp/src/arrow/json/object_writer.cc | 81 ----------------------
cpp/src/arrow/json/object_writer.h | 49 -------------
cpp/src/arrow/meson.build | 1 -
cpp/src/parquet/CMakeLists.txt | 6 +-
.../encryption/file_system_key_material_store.cc | 10 +--
cpp/src/parquet/encryption/key_material.cc | 40 +++++++----
cpp/src/parquet/encryption/key_metadata.cc | 19 ++---
.../parquet/encryption/local_wrap_kms_client.cc | 16 +++--
12 files changed, 70 insertions(+), 169 deletions(-)
diff --git a/cpp/src/arrow/CMakeLists.txt b/cpp/src/arrow/CMakeLists.txt
index 64fb4d12a5..7211bf5476 100644
--- a/cpp/src/arrow/CMakeLists.txt
+++ b/cpp/src/arrow/CMakeLists.txt
@@ -1042,7 +1042,6 @@ if(ARROW_JSON)
json/from_string.cc
json/json_writer_internal.cc
json/object_parser.cc
- json/object_writer.cc
json/parser.cc
json/reader.cc)
foreach(ARROW_JSON_TARGET ${ARROW_JSON_TARGETS})
diff --git a/cpp/src/arrow/json/json_writer_internal.cc
b/cpp/src/arrow/json/json_writer_internal.cc
index 11fe70a741..49038f26b0 100644
--- a/cpp/src/arrow/json/json_writer_internal.cc
+++ b/cpp/src/arrow/json/json_writer_internal.cc
@@ -115,4 +115,14 @@ void JsonWriter::MaybeComma() {
}
}
+void JsonWriter::StringField(std::string_view key, std::string_view value) {
+ Key(key);
+ String(value);
+}
+
+void JsonWriter::BoolField(std::string_view key, bool value) {
+ Key(key);
+ Bool(value);
+}
+
} // namespace arrow::json
diff --git a/cpp/src/arrow/json/json_writer_internal.h
b/cpp/src/arrow/json/json_writer_internal.h
index e4d6e49885..4173cb4c51 100644
--- a/cpp/src/arrow/json/json_writer_internal.h
+++ b/cpp/src/arrow/json/json_writer_internal.h
@@ -52,6 +52,9 @@ class ARROW_EXPORT JsonWriter {
void Null();
+ void StringField(std::string_view key, std::string_view value);
+ void BoolField(std::string_view key, bool value);
+
std::string_view GetString() const;
void Clear();
diff --git a/cpp/src/arrow/json/meson.build b/cpp/src/arrow/json/meson.build
index a2aa69ecf7..edf92a46fd 100644
--- a/cpp/src/arrow/json/meson.build
+++ b/cpp/src/arrow/json/meson.build
@@ -22,9 +22,9 @@ exc = executable(
'chunker_test.cc',
'converter_test.cc',
'from_string_test.cc',
+ 'json_writer_internal_test.cc',
'parser_test.cc',
'reader_test.cc',
- 'json_writer_internal_test.cc',
],
dependencies: [arrow_test_dep, rapidjson_dep],
)
@@ -45,7 +45,6 @@ install_headers(
'converter.h',
'from_string.h',
'object_parser.h',
- 'object_writer.h',
'options.h',
'parser.h',
'rapidjson_defs.h',
diff --git a/cpp/src/arrow/json/object_writer.cc
b/cpp/src/arrow/json/object_writer.cc
deleted file mode 100644
index 3277807880..0000000000
--- a/cpp/src/arrow/json/object_writer.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-#include "arrow/json/object_writer.h"
-#include "arrow/json/rapidjson_defs.h" // IWYU pragma: keep
-
-#include <rapidjson/document.h>
-#include <rapidjson/stringbuffer.h>
-#include <rapidjson/writer.h>
-
-namespace rj = arrow::rapidjson;
-
-namespace arrow {
-namespace json {
-namespace internal {
-
-class ObjectWriter::Impl {
- public:
- Impl() : root_(rj::kObjectType) {}
-
- void SetString(std::string_view key, std::string_view value) {
- rj::Document::AllocatorType& allocator = document_.GetAllocator();
-
- rj::Value str_key(key.data(), allocator);
- rj::Value str_value(value.data(), allocator);
-
- root_.AddMember(str_key, str_value, allocator);
- }
-
- void SetBool(std::string_view key, bool value) {
- rj::Document::AllocatorType& allocator = document_.GetAllocator();
-
- rj::Value str_key(key.data(), allocator);
-
- root_.AddMember(str_key, value, allocator);
- }
-
- std::string Serialize() {
- rj::StringBuffer buffer;
- rj::Writer<rj::StringBuffer> writer(buffer);
- root_.Accept(writer);
-
- return buffer.GetString();
- }
-
- private:
- rj::Document document_;
- rj::Value root_;
-};
-
-ObjectWriter::ObjectWriter() : impl_(new ObjectWriter::Impl()) {}
-
-ObjectWriter::~ObjectWriter() = default;
-
-void ObjectWriter::SetString(std::string_view key, std::string_view value) {
- impl_->SetString(key, value);
-}
-
-void ObjectWriter::SetBool(std::string_view key, bool value) {
- impl_->SetBool(key, value);
-}
-
-std::string ObjectWriter::Serialize() { return impl_->Serialize(); }
-
-} // namespace internal
-} // namespace json
-} // namespace arrow
diff --git a/cpp/src/arrow/json/object_writer.h
b/cpp/src/arrow/json/object_writer.h
deleted file mode 100644
index cf1ce62194..0000000000
--- a/cpp/src/arrow/json/object_writer.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-#pragma once
-
-#include <memory>
-#include <string>
-#include <string_view>
-
-#include "arrow/util/visibility.h"
-
-namespace arrow {
-namespace json {
-namespace internal {
-
-/// This class is a helper to serialize a json object to a string.
-/// It uses rapidjson in implementation.
-class ARROW_EXPORT ObjectWriter {
- public:
- ObjectWriter();
- ~ObjectWriter();
-
- void SetString(std::string_view key, std::string_view value);
- void SetBool(std::string_view key, bool value);
-
- std::string Serialize();
-
- private:
- class Impl;
- std::unique_ptr<Impl> impl_;
-};
-
-} // namespace internal
-} // namespace json
-} // namespace arrow
diff --git a/cpp/src/arrow/meson.build b/cpp/src/arrow/meson.build
index ef044f6c42..955ef78973 100644
--- a/cpp/src/arrow/meson.build
+++ b/cpp/src/arrow/meson.build
@@ -516,7 +516,6 @@ if needs_json
'json/from_string.cc',
'json/json_writer_internal.cc',
'json/object_parser.cc',
- 'json/object_writer.cc',
'json/options.cc',
'json/parser.cc',
'json/reader.cc',
diff --git a/cpp/src/parquet/CMakeLists.txt b/cpp/src/parquet/CMakeLists.txt
index f8a42b5b96..e5860d8919 100644
--- a/cpp/src/parquet/CMakeLists.txt
+++ b/cpp/src/parquet/CMakeLists.txt
@@ -263,9 +263,9 @@ endif()
list(APPEND PARQUET_SHARED_LINK_LIBS arrow_shared)
-# Add RapidJSON libraries
-list(APPEND PARQUET_SHARED_PRIVATE_LINK_LIBS RapidJSON)
-list(APPEND PARQUET_STATIC_LINK_LIBS RapidJSON)
+# Add RapidJSON & simdjson libraries
+list(APPEND PARQUET_SHARED_PRIVATE_LINK_LIBS RapidJSON simdjson::simdjson)
+list(APPEND PARQUET_STATIC_LINK_LIBS RapidJSON simdjson::simdjson)
# These are libraries that we will link privately with parquet_shared (as they
# do not need to be linked transitively by other linkers)
diff --git a/cpp/src/parquet/encryption/file_system_key_material_store.cc
b/cpp/src/parquet/encryption/file_system_key_material_store.cc
index fb8c92ceaf..e5b215a846 100644
--- a/cpp/src/parquet/encryption/file_system_key_material_store.cc
+++ b/cpp/src/parquet/encryption/file_system_key_material_store.cc
@@ -20,8 +20,8 @@
#include "arrow/buffer.h"
#include "arrow/filesystem/filesystem.h"
#include "arrow/filesystem/path_util.h"
+#include "arrow/json/json_writer_internal.h"
#include "arrow/json/object_parser.h"
-#include "arrow/json/object_writer.h"
#include "arrow/result.h"
#include "parquet/encryption/file_system_key_material_store.h"
@@ -81,11 +81,13 @@ void FileSystemKeyMaterialStore::LoadKeyMaterialMap() {
}
std::string FileSystemKeyMaterialStore::BuildKeyMaterialMapJson() {
- ::arrow::json::internal::ObjectWriter writer;
+ ::arrow::json::JsonWriter writer;
+ writer.StartObject();
for (const auto& it : key_material_map_) {
- writer.SetString(it.first, it.second);
+ writer.StringField(it.first, it.second);
}
- return writer.Serialize();
+ writer.EndObject();
+ return std::string(writer.GetString());
}
void FileSystemKeyMaterialStore::SaveMaterial() {
diff --git a/cpp/src/parquet/encryption/key_material.cc
b/cpp/src/parquet/encryption/key_material.cc
index 1cebf5900f..67f838c1df 100644
--- a/cpp/src/parquet/encryption/key_material.cc
+++ b/cpp/src/parquet/encryption/key_material.cc
@@ -15,15 +15,15 @@
// specific language governing permissions and limitations
// under the License.
+#include "arrow/json/json_writer_internal.h"
#include "arrow/json/object_parser.h"
-#include "arrow/json/object_writer.h"
#include "parquet/encryption/key_material.h"
#include "parquet/encryption/key_metadata.h"
#include "parquet/exception.h"
+using ::arrow::json::JsonWriter;
using ::arrow::json::internal::ObjectParser;
-using ::arrow::json::internal::ObjectWriter;
namespace parquet::encryption {
@@ -122,36 +122,48 @@ std::string KeyMaterial::SerializeToJson(
bool is_double_wrapped, const std::string& kek_id,
const std::string& encoded_wrapped_kek, const std::string&
encoded_wrapped_dek,
bool is_internal_storage) {
- ObjectWriter json_writer;
- json_writer.SetString(kKeyMaterialTypeField, kKeyMaterialType1);
+ JsonWriter json_writer;
+
+ json_writer.StartObject();
+
+ json_writer.StringField(kKeyMaterialTypeField, kKeyMaterialType1);
if (is_internal_storage) {
// 1. for internal storage, key material and key metadata are the same.
// adding the "internalStorage" field that belongs to KeyMetadata.
- json_writer.SetBool(KeyMetadata::kKeyMaterialInternalStorageField, true);
+ json_writer.BoolField(KeyMetadata::kKeyMaterialInternalStorageField, true);
}
+
// 2. Write isFooterKey
- json_writer.SetBool(kIsFooterKeyField, is_footer_key);
+ json_writer.BoolField(kIsFooterKeyField, is_footer_key);
+
if (is_footer_key) {
// 3. For footer key, write KMS Instance ID
- json_writer.SetString(kKmsInstanceIdField, kms_instance_id);
+ json_writer.StringField(kKmsInstanceIdField, kms_instance_id);
+
// 4. For footer key, write KMS Instance URL
- json_writer.SetString(kKmsInstanceUrlField, kms_instance_url);
+ json_writer.StringField(kKmsInstanceUrlField, kms_instance_url);
}
+
// 5. Write master key ID
- json_writer.SetString(kMasterKeyIdField, master_key_id);
+ json_writer.StringField(kMasterKeyIdField, master_key_id);
+
// 6. Write wrapped DEK
- json_writer.SetString(kWrappedDataEncryptionKeyField, encoded_wrapped_dek);
+ json_writer.StringField(kWrappedDataEncryptionKeyField, encoded_wrapped_dek);
+
// 7. Write isDoubleWrapped
- json_writer.SetBool(kDoubleWrappingField, is_double_wrapped);
+ json_writer.BoolField(kDoubleWrappingField, is_double_wrapped);
+
if (is_double_wrapped) {
// 8. In double wrapping mode, write KEK ID
- json_writer.SetString(kKeyEncryptionKeyIdField, kek_id);
+ json_writer.StringField(kKeyEncryptionKeyIdField, kek_id);
+
// 9. In double wrapping mode, write wrapped KEK
- json_writer.SetString(kWrappedKeyEncryptionKeyField, encoded_wrapped_kek);
+ json_writer.StringField(kWrappedKeyEncryptionKeyField,
encoded_wrapped_kek);
}
- return json_writer.Serialize();
+ json_writer.EndObject();
+ return std::string(json_writer.GetString());
}
} // namespace parquet::encryption
diff --git a/cpp/src/parquet/encryption/key_metadata.cc
b/cpp/src/parquet/encryption/key_metadata.cc
index e23a67b6b8..ed6c62955c 100644
--- a/cpp/src/parquet/encryption/key_metadata.cc
+++ b/cpp/src/parquet/encryption/key_metadata.cc
@@ -15,14 +15,14 @@
// specific language governing permissions and limitations
// under the License.
+#include "arrow/json/json_writer_internal.h"
#include "arrow/json/object_parser.h"
-#include "arrow/json/object_writer.h"
#include "parquet/encryption/key_metadata.h"
#include "parquet/exception.h"
+using ::arrow::json::JsonWriter;
using ::arrow::json::internal::ObjectParser;
-using ::arrow::json::internal::ObjectWriter;
namespace parquet::encryption {
@@ -73,15 +73,18 @@ KeyMetadata KeyMetadata::Parse(const std::string&
key_metadata) {
// directly
std::string KeyMetadata::CreateSerializedForExternalMaterial(
const std::string& key_reference) {
- ObjectWriter json_writer;
+ JsonWriter json_writer;
- json_writer.SetString(KeyMaterial::kKeyMaterialTypeField,
- KeyMaterial::kKeyMaterialType1);
- json_writer.SetBool(kKeyMaterialInternalStorageField, false);
+ json_writer.StartObject();
- json_writer.SetString(kKeyReferenceField, key_reference);
+ json_writer.StringField(KeyMaterial::kKeyMaterialTypeField,
+ KeyMaterial::kKeyMaterialType1);
+ json_writer.BoolField(kKeyMaterialInternalStorageField, false);
+ json_writer.StringField(kKeyReferenceField, key_reference);
- return json_writer.Serialize();
+ json_writer.EndObject();
+
+ return std::string(json_writer.GetString());
}
} // namespace parquet::encryption
diff --git a/cpp/src/parquet/encryption/local_wrap_kms_client.cc
b/cpp/src/parquet/encryption/local_wrap_kms_client.cc
index 80543c2932..b2a6872af5 100644
--- a/cpp/src/parquet/encryption/local_wrap_kms_client.cc
+++ b/cpp/src/parquet/encryption/local_wrap_kms_client.cc
@@ -15,16 +15,16 @@
// specific language governing permissions and limitations
// under the License.
+#include "arrow/json/json_writer_internal.h"
#include "arrow/json/object_parser.h"
-#include "arrow/json/object_writer.h"
#include "arrow/util/secure_string.h"
#include "parquet/encryption/key_toolkit_internal.h"
#include "parquet/encryption/local_wrap_kms_client.h"
#include "parquet/exception.h"
+using ::arrow::json::JsonWriter;
using ::arrow::json::internal::ObjectParser;
-using ::arrow::json::internal::ObjectWriter;
using ::arrow::util::SecureString;
namespace parquet::encryption {
@@ -41,12 +41,16 @@ LocalWrapKmsClient::LocalKeyWrap::LocalKeyWrap(std::string
master_key_version,
std::string LocalWrapKmsClient::LocalKeyWrap::CreateSerialized(
const std::string& encrypted_encoded_key) {
- ObjectWriter json_writer;
+ JsonWriter json_writer;
- json_writer.SetString(kLocalWrapKeyVersionField, kLocalWrapNoKeyVersion);
- json_writer.SetString(kLocalWrapEncryptedKeyField, encrypted_encoded_key);
+ json_writer.StartObject();
- return json_writer.Serialize();
+ json_writer.StringField(kLocalWrapKeyVersionField, kLocalWrapNoKeyVersion);
+ json_writer.StringField(kLocalWrapEncryptedKeyField, encrypted_encoded_key);
+
+ json_writer.EndObject();
+
+ return std::string(json_writer.GetString());
}
LocalWrapKmsClient::LocalKeyWrap LocalWrapKmsClient::LocalKeyWrap::Parse(