Skip to content

Commit fa2b7b6

Browse files
committed
[ntuple] Add RPageSinkFile::CloneWithDifferentName
Writing analogue to RPageSourceFile::OpenWithDifferentAnchor, it allows to derive a new Sink from an existing one using the same underlying directory but writing to a different RNTuple.
1 parent 321ad35 commit fa2b7b6

13 files changed

+107
-1
lines changed

tree/ntuple/inc/ROOT/RMiniFile.hxx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,13 @@ public:
261261
RNTupleFileWriter &operator=(RNTupleFileWriter &&other) = delete;
262262
~RNTupleFileWriter();
263263

264+
/// Creates a new RNTupleFileWriter with the same underlying TDirectory as this but writing to a different
265+
/// RNTuple named `ntupleName`. This class is not thread safe, so one of the two writers may be writing to the file
266+
/// at the same time.
267+
/// This method is currently only supported for TFile-based Writers and will throw an exception if that's not the
268+
/// case.
269+
std::unique_ptr<RNTupleFileWriter> CloneWithDifferentName(std::string_view ntupleName) const;
270+
264271
/// Seek a simple writer to offset. Note that previous data is not flushed immediately, but only by the next write
265272
/// (if necessary).
266273
void Seek(std::uint64_t offset);
@@ -286,6 +293,8 @@ public:
286293
void UpdateStreamerInfos(const ROOT::Internal::RNTupleSerializer::StreamerInfoMap_t &streamerInfos);
287294
/// Writes the RNTuple key to the file so that the header and footer keys can be found
288295
void Commit(int compression = RCompressionSetting::EDefaults::kUseGeneralPurpose);
296+
297+
std::string_view GetNTupleName() const { return fNTupleName; }
289298
};
290299

291300
} // namespace Internal

tree/ntuple/inc/ROOT/RPageNullSink.hxx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ public:
106106
void CommitStagedClusters(std::span<RStagedCluster>) final {}
107107
void CommitClusterGroup() final {}
108108
void CommitDatasetImpl() final {}
109+
110+
std::unique_ptr<RPageSink> CloneWithDifferentName(std::string_view, const RNTupleWriteOptions &) const final
111+
{
112+
throw ROOT::RException(R__FAIL("cannot clone null sink"));
113+
}
109114
};
110115

111116
} // namespace Internal

tree/ntuple/inc/ROOT/RPageSinkBuf.hxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ public:
152152
void CommitDatasetImpl() final;
153153

154154
RPage ReservePage(ColumnHandle_t columnHandle, std::size_t nElements) final;
155+
156+
std::unique_ptr<RPageSink>
157+
CloneWithDifferentName(std::string_view name, const RNTupleWriteOptions &opts) const final;
155158
}; // RPageSinkBuf
156159

157160
} // namespace Internal

tree/ntuple/inc/ROOT/RPageStorage.hxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,9 @@ public:
387387
/// CommitClusterGroup (or the beginning of writing).
388388
virtual void CommitClusterGroup() = 0;
389389

390+
virtual std::unique_ptr<RPageSink>
391+
CloneWithDifferentName(std::string_view name, const RNTupleWriteOptions &opts) const = 0;
392+
390393
/// The registered callback is executed at the beginning of CommitDataset();
391394
void RegisterOnCommitDatasetCallback(Callback_t callback) { fOnDatasetCommitCallbacks.emplace_back(callback); }
392395
/// Run the registered callbacks and finalize the current cluster and the entrire data set.

tree/ntuple/inc/ROOT/RPageStorageDaos.hxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ protected:
140140
public:
141141
RPageSinkDaos(std::string_view ntupleName, std::string_view uri, const ROOT::RNTupleWriteOptions &options);
142142
~RPageSinkDaos() override;
143+
144+
std::unique_ptr<ROOT::Internal::RPageSink>
145+
CloneWithDifferentName(std::string_view name, const ROOT::RNTupleWriteOptions &opts) const final;
143146
}; // class RPageSinkDaos
144147

145148
// clang-format off

tree/ntuple/inc/ROOT/RPageStorageFile.hxx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ private:
7373
ROOT::Internal::RNTupleSerializer::StreamerInfoMap_t fInfosOfClassFields;
7474

7575
RPageSinkFile(std::string_view ntupleName, const ROOT::RNTupleWriteOptions &options);
76+
RPageSinkFile(std::unique_ptr<ROOT::Internal::RNTupleFileWriter> writer, const ROOT::RNTupleWriteOptions &options);
7677

7778
/// We pass bytesPacked so that TFile::ls() reports a reasonable value for the compression ratio of the corresponding
7879
/// key. It is not strictly necessary to write and read the sealed page.
@@ -109,6 +110,11 @@ public:
109110
~RPageSinkFile() override;
110111

111112
void UpdateSchema(const ROOT::Internal::RNTupleModelChangeset &changeset, ROOT::NTupleSize_t firstEntry) final;
113+
114+
/// Creates a new sink that uses the same underlying file/directory but writes to a different RNTuple with the
115+
/// given `name`.
116+
std::unique_ptr<RPageSink>
117+
CloneWithDifferentName(std::string_view name, const ROOT::RNTupleWriteOptions &opts) const override;
112118
}; // class RPageSinkFile
113119

114120
// clang-format off

tree/ntuple/src/RMiniFile.cxx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1232,7 +1232,7 @@ ROOT::Internal::RNTupleFileWriter::RNTupleFileWriter(std::string_view name, std:
12321232
fStreamerInfoMap[infoRNTuple->GetNumber()] = infoRNTuple;
12331233
}
12341234

1235-
ROOT::Internal::RNTupleFileWriter::~RNTupleFileWriter() {}
1235+
ROOT::Internal::RNTupleFileWriter::~RNTupleFileWriter() = default;
12361236

12371237
std::unique_ptr<ROOT::Internal::RNTupleFileWriter>
12381238
ROOT::Internal::RNTupleFileWriter::Recreate(std::string_view ntupleName, std::string_view path,
@@ -1317,6 +1317,16 @@ ROOT::Internal::RNTupleFileWriter::Append(std::string_view ntupleName, ROOT::Exp
13171317
return writer;
13181318
}
13191319

1320+
std::unique_ptr<ROOT::Internal::RNTupleFileWriter>
1321+
ROOT::Internal::RNTupleFileWriter::CloneWithDifferentName(std::string_view ntupleName) const
1322+
{
1323+
if (auto *file = std::get_if<RFileProper>(&fFile)) {
1324+
return Append(ntupleName, *file->fDirectory, fNTupleAnchor.fMaxKeySize);
1325+
}
1326+
// TODO: support also non-TFile-based writers
1327+
throw ROOT::RException(R__FAIL("cannot clone a non-TFile-based RNTupleFileWriter."));
1328+
}
1329+
13201330
void ROOT::Internal::RNTupleFileWriter::Seek(std::uint64_t offset)
13211331
{
13221332
RFileSimple *fileSimple = std::get_if<RFileSimple>(&fFile);

tree/ntuple/src/RNTupleParallelWriter.cxx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ class RPageSynchronizingSink : public RPageSink {
113113
}
114114

115115
RSinkGuard GetSinkGuard() final { return RSinkGuard(fMutex); }
116+
117+
std::unique_ptr<RPageSink> CloneWithDifferentName(std::string_view, const ROOT::RNTupleWriteOptions &) const final
118+
{
119+
throw ROOT::RException(R__FAIL("cloning a RPageSynchronizingSink is not implemented yet"));
120+
}
116121
};
117122

118123
} // namespace

tree/ntuple/src/RPageSinkBuf.cxx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,3 +321,9 @@ ROOT::Internal::RPage ROOT::Internal::RPageSinkBuf::ReservePage(ColumnHandle_t c
321321
{
322322
return fInnerSink->ReservePage(columnHandle, nElements);
323323
}
324+
325+
std::unique_ptr<ROOT::Internal::RPageSink>
326+
ROOT::Internal::RPageSinkBuf::CloneWithDifferentName(std::string_view name, const RNTupleWriteOptions &opts) const
327+
{
328+
return fInnerSink->CloneWithDifferentName(name, opts);
329+
}

tree/ntuple/src/RPageStorageDaos.cxx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,13 @@ void ROOT::Experimental::Internal::RPageSinkDaos::WriteNTupleAnchor()
482482
kDistributionKeyDefault, kAttributeKeyAnchor, kCidMetadata);
483483
}
484484

485+
std::unique_ptr<ROOT::Internal::RPageSink>
486+
ROOT::Experimental::Internal::RPageSinkDaos::CloneWithDifferentName(std::string_view /*name*/,
487+
const ROOT::RNTupleWriteOptions & /*opts*/) const
488+
{
489+
throw ROOT::RException(R__FAIL("cloning a DAOS sink is not implemented yet"));
490+
}
491+
485492
////////////////////////////////////////////////////////////////////////////////
486493

487494
ROOT::Experimental::Internal::RPageSourceDaos::RPageSourceDaos(std::string_view ntupleName, std::string_view uri,

0 commit comments

Comments
 (0)