Skip to content

[ntuple] Add S3 anchor and its tests for S3 backend#22470

Open
JasMehta08 wants to merge 1 commit into
root-project:masterfrom
JasMehta08:ntuple-s3-anchor
Open

[ntuple] Add S3 anchor and its tests for S3 backend#22470
JasMehta08 wants to merge 1 commit into
root-project:masterfrom
JasMehta08:ntuple-s3-anchor

Conversation

@JasMehta08

Copy link
Copy Markdown
Contributor

This Pull request:

(Is a part of the GSoC 2026 project S3 Backend for RNTuple.)

Creates the anchor for the S3 backend.

Changes or fixes:

  • Adds S3NTupleAnchor struct, using JSON to store the anchor data.
  • Adds ROOT_BUILD_OPTION(s3 OFF "Enable RNTuple support for S3-compatible object storage")to conditionally compile.
  • Adds tests that cover round-trip, version guard, malformed input, type mismatches, boundary values, and forward compatibility.

Checklist:

  • tested changes locally

@JasMehta08

Copy link
Copy Markdown
Contributor Author

@jblomer

I have made the changes so that the build for S3 backend only occurs when curl is present, and removed the s3 flag.

@jblomer jblomer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice!

Comment thread tree/ntuple/inc/ROOT/RPageStorageS3.hxx Outdated
if the anchor exists, the entire ntuple is complete.
*/
// clang-format on
struct RS3NTupleAnchor {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe better:

Suggested change
struct RS3NTupleAnchor {
struct RNTupleAnchorS3 {

Comment thread tree/ntuple/inc/ROOT/RPageStorageS3.hxx Outdated
Comment on lines +53 to +54
std::uint32_t fNBytesHeader = 0;
std::uint32_t fLenHeader = 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and for the footer: since we use 64bits in the regular anchor, let's do the same here.

Comment thread tree/ntuple/inc/ROOT/RPageStorageS3.hxx Outdated
bool operator==(const RS3NTupleAnchor &other) const;

/// Serialize the anchor to a JSON string suitable for storage at the base URL
std::string Serialize() const;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::string Serialize() const;
std::string ToJSON() const;

Comment thread tree/ntuple/inc/ROOT/RPageStorageS3.hxx Outdated
/// Serialize the anchor to a JSON string suitable for storage at the base URL
std::string Serialize() const;
/// Deserialize the anchor from a JSON string. Returns an error on malformed or incompatible input.
RResult<void> Deserialize(const std::string &json);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
RResult<void> Deserialize(const std::string &json);
RResult<void> FromJSON(const std::string &json);

Comment thread tree/ntuple/src/RPageStorageS3.cxx Outdated
Comment on lines +38 to +51
jsonAnchor["anchor_version"] = fVersionAnchor;
jsonAnchor["format_version_epoch"] = fVersionEpoch;
jsonAnchor["format_version_major"] = fVersionMajor;
jsonAnchor["format_version_minor"] = fVersionMinor;
jsonAnchor["format_version_patch"] = fVersionPatch;
jsonAnchor["url_template"] = fUrlTemplate;
jsonAnchor["header_obj_id"] = fHeaderObjId;
jsonAnchor["header_offset"] = fHeaderOffset;
jsonAnchor["nbytes_header"] = fNBytesHeader;
jsonAnchor["len_header"] = fLenHeader;
jsonAnchor["footer_obj_id"] = fFooterObjId;
jsonAnchor["footer_offset"] = fFooterOffset;
jsonAnchor["nbytes_footer"] = fNBytesFooter;
jsonAnchor["len_footer"] = fLenFooter;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, since we use camelCase in the C++ code, let's do the same in JSON.

Comment thread tree/ntuple/CMakeLists.txt Outdated
if(curl)
set(ROOTNTuple_EXTRA_HEADERS ${ROOTNTuple_EXTRA_HEADERS} ROOT/RPageStorageS3.hxx)
target_sources(ROOTNTuple PRIVATE src/RPageStorageS3.cxx)
target_compile_definitions(ROOTNTuple PRIVATE R__ENABLE_S3)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's wait until we actually need the define.

Comment thread tree/ntuple/inc/ROOT/RPageStorageS3.hxx Outdated
/// Serialize the anchor to a JSON string suitable for storage at the base URL
std::string Serialize() const;
/// Deserialize the anchor from a JSON string. Returns an error on malformed or incompatible input.
RResult<void> Deserialize(const std::string &json);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is easier to make this method static and return a RResult<RS3NTupleAnchor>. Then we don't need to care about object reset.

Comment thread tree/ntuple/inc/ROOT/RPageStorageS3.hxx Outdated
// clang-format on
struct RS3NTupleAnchor {
/// Allows evolving the anchor JSON schema in future versions
std::uint32_t fVersionAnchor = 1;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we gain anything by reserving version 0. I think we can just start with it.

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

Test Results

    21 files      21 suites   3d 7h 54m 42s ⏱️
 3 857 tests  3 849 ✅   0 💤 8 ❌
73 349 runs  73 238 ✅ 103 💤 8 ❌

For more details on these failures, see this check.

Results for commit 3a8cec6.

@JasMehta08

Copy link
Copy Markdown
Contributor Author

@jblomer

I have made the update according to the comments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants