Skip to content

[ntuple] Add RPageSinkS3 for the basic S3 write path (Mode B)#22653

Open
JasMehta08 wants to merge 3 commits into
root-project:masterfrom
JasMehta08:ntuple-s3-sink
Open

[ntuple] Add RPageSinkS3 for the basic S3 write path (Mode B)#22653
JasMehta08 wants to merge 3 commits into
root-project:masterfrom
JasMehta08:ntuple-s3-sink

Conversation

@JasMehta08

Copy link
Copy Markdown
Contributor

This Pull request:

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

Adds RPageSinkS3, the write path of the experimental S3 storage backend for RNTuple.

Changes or fixes:

  • RPageSinkS3 (Mode B full write path): InitImpl (header), CommitPageImpl/CommitSealedPageImpl (one S3 object per sealed page, kTypeObject64 locator), StageClusterImpl, CommitClusterGroupImpl (page list), and CommitDatasetImpl (footer, then the JSON anchor written last for atomicity).

Checklist:

  • tested changes locally

@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! Some discussion points.

Comment thread tree/ntuple/CMakeLists.txt Outdated
Comment thread tree/ntuple/inc/ROOT/RPageStorageS3.hxx Outdated
Comment thread tree/ntuple/inc/ROOT/RPageStorageS3.hxx Outdated
Comment thread tree/ntuple/src/RPageStorage.cxx Outdated
Comment thread tree/ntuple/src/RPageStorageS3.cxx Outdated
Comment thread tree/ntuple/src/RPageStorageS3.cxx Outdated
Comment thread tree/ntuple/src/RPageStorageS3.cxx Outdated
fAnchor.fLenHeader = length;
}

ROOT::RNTupleLocator ROOT::Experimental::Internal::RPageSinkS3::CommitPageImpl(ColumnHandle_t columnHandle,

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 this is exactly the same code for file, DAOS, and S3. I suggest to make a first, preparatory commit that moves this logic to RPagePersistentSink::CommitPage() (the only place where it is used) and to remove CommitPageImpl() altogether.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Should I create a separate PR or just a commit in this PR before the S3 sink commit

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 can be the same PR, just a different commit

@JasMehta08 JasMehta08 Jun 28, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@jblomer

I was working on removing CommitPageImpl() altogether. I noticed a few things,

There are 5 places where it was present,

RPagePersistentSink, RPageSinkFile (A little different), RPageSinkDaos, RPageSinkS3 , RPageSinkTestLocator in ntuple_compat.cxx (a test) (different)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

  • The file one differed, Its CommitPageImpl returns WriteSealedPage(sealedPage, element->GetPackedSize(page.GetNElements())) instead of CommitSealedPageImpl(columnHandle.fPhysicalId, sealedPage) like DAOS and S3.
  • I checked whether routing the new common CommitPage() through CommitSealedPageImpl() changes anything for File, and it shouldn't, File's CommitSealedPageImpl computes the same packed size ((nBits * nElements + 7) / 8, which is exactly what GetPackedSize() returns) and calls the same WriteSealedPage. So the written blob and the returned locator are identical.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

  • The RPageSinkTestLocator, is a bit tougher,
  • RPageSinkTestLocator puts an unknown locator type by overriding CommitPageImpl and shadowing the (non-virtual) WriteSealedPage. With CommitPageImpl gone, the base would call RPageSinkFile::CommitSealedPageImpl → RPageSinkFile::WriteSealedPage(statically bound), so the test's shadow would silently stop being used.
  • To keep it working I thought of changing RPageSinkFile::CommitSealedPageImpl from final to override and changed the test to override CommitSealedPageImpl directly. Let me know if you would prefer another approach to it.

Comment thread tree/ntuple/inc/ROOT/RPageStorageS3.hxx Outdated
// Upload the anchor LAST: once it exists at the base URL, a reader can assume the whole ntuple
// is complete. Never upload it before all other objects are in place.
const auto anchorJson = fAnchor.ToJSON();
PutObject(fBaseUrl, reinterpret_cast<const unsigned char *>(anchorJson.data()), anchorJson.size());

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.

One thing I forgot (not for this PR): we should checksum the anchor. E.g., using some canonical json normalization. Let's discuss this in the next meeting.

Comment thread tree/ntuple/src/RPageStorageS3.cxx Outdated
@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown

Test Results

    21 files      21 suites   3d 2h 11m 6s ⏱️
 3 852 tests  3 852 ✅ 0 💤 0 ❌
72 671 runs  72 671 ✅ 0 💤 0 ❌

Results for commit 621a5d3.

♻️ This comment has been updated with latest results.

Comment thread net/curl/inc/ROOT/RCurlConnection.hxx Outdated
@jblomer

jblomer commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

We have some merge conflicts which need to be resolved first

@JasMehta08

Copy link
Copy Markdown
Contributor Author

@jblomer

I have resolved the conflicts

{
// The hidden (attribute-set) ntuple is stored under a reserved "_clone" sub-prefix so its objects and
// anchor can never collide with the main ntuple's numeric object keys ($baseurl/0, $baseurl/1, ...).
std::string cloneBaseUrl = fBaseUrl + "/_clone/" + std::string(name);

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.

We probably should make this a template, too, and add it to the anchor. Like fCloneTemplate = ${baseurl}/_clone/${name}. Can be a follow-up PR.

Comment thread tree/ntuple/inc/ROOT/RPageStorageS3.hxx Outdated

if (ROOT::StartsWith(location, "ntpl+s3")) {
#ifdef R__ENABLE_S3
return std::make_unique<ROOT::Experimental::Internal::RPageSinkS3>(ntupleName, location, options);

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.

Shouldn't this need the (guarded) ROOT/RPageStorageS3.hxx include?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It is included near the top of the file at line 30 as

#ifdef R__ENABLE_S3
#include <ROOT/RPageStorageS3.hxx>
#endif

Comment thread tree/ntuple/src/RPageStorage.cxx Outdated
Comment thread tree/ntuple/src/RPageStorageS3.cxx Outdated
Comment thread tree/ntuple/src/RPageStorageS3.cxx Outdated
Comment thread tree/ntuple/src/RPageStorageS3.cxx Outdated
@JasMehta08

Copy link
Copy Markdown
Contributor Author

@jblomer

I have made the changes according to the comments please have a look

@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.

Thanks! For the Windows failures, the test should use gSystem's wrapper for setenv and unsetenv.

@JasMehta08

Copy link
Copy Markdown
Contributor Author

@jblomer

I have fixed the issue with setenv and unsetenv and used the gSystem's implementation.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants