Skip to content

Commit 613f3e4

Browse files
committed
[ntuple] add cloning for RImplSimple-based writer
1 parent 130463a commit 613f3e4

2 files changed

Lines changed: 34 additions & 18 deletions

File tree

tree/ntuple/inc/ROOT/RMiniFile.hxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ private:
159159

160160
/// Whether the C file stream has been opened with Direct I/O, introducing alignment requirements.
161161
bool fDirectIO = false;
162+
bool fIsClone = false;
162163

163164
struct RSharedData {
164165
/// For the simplest cases, a C file stream can be used for writing

tree/ntuple/src/RMiniFile.cxx

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,11 +1335,22 @@ ROOT::Internal::RNTupleFileWriter::Append(std::string_view ntupleName, ROOT::Exp
13351335
std::unique_ptr<ROOT::Internal::RNTupleFileWriter>
13361336
ROOT::Internal::RNTupleFileWriter::CloneWithDifferentName(std::string_view ntupleName) const
13371337
{
1338-
if (auto *file = std::get_if<RImplTFile>(&fFile)) {
1339-
return Append(ntupleName, *file->fDirectory, fNTupleAnchor.fMaxKeySize);
1340-
}
1341-
// TODO: support also non-TFile-based writers
1342-
throw ROOT::RException(R__FAIL("cannot clone a non-TFile-based RNTupleFileWriter."));
1338+
if (auto *tfile = std::get_if<RImplTFile>(&fFile)) {
1339+
return Append(ntupleName, *tfile->fDirectory, fNTupleAnchor.fMaxKeySize);
1340+
} else if (auto *file = std::get_if<RImplSimple>(&fFile)) {
1341+
if (fIsBare)
1342+
throw ROOT::RException(R__FAIL("cloning a bare file is currently unsupported"));
1343+
1344+
auto writer =
1345+
std::unique_ptr<RNTupleFileWriter>(new RNTupleFileWriter(ntupleName, fNTupleAnchor.GetMaxKeySize()));
1346+
auto &clonedFile = std::get<RImplSimple>(writer->fFile);
1347+
clonedFile.fShared = file->fShared;
1348+
clonedFile.fDirectIO = file->fDirectIO;
1349+
clonedFile.fIsClone = true;
1350+
return writer;
1351+
}
1352+
// TODO: support also RFile-based writers
1353+
throw ROOT::RException(R__FAIL("cannot clone an RFile-based RNTupleFileWriter."));
13431354
}
13441355

13451356
void ROOT::Internal::RNTupleFileWriter::Seek(std::uint64_t offset)
@@ -1386,13 +1397,15 @@ void ROOT::Internal::RNTupleFileWriter::Commit(int compression)
13861397
auto &fileSimple = std::get<RImplSimple>(fFile);
13871398

13881399
if (fIsBare) {
1400+
assert(!fileSimple.fIsClone);
1401+
13891402
RTFNTuple ntupleOnDisk(fNTupleAnchor);
13901403
// Compute the checksum
1404+
const auto &controlBlock = fileSimple.fShared->fControlBlock;
1405+
unsigned char *headerBlock = fileSimple.fShared->fHeaderBlock;
13911406
std::uint64_t checksum = XXH3_64bits(ntupleOnDisk.GetPtrCkData(), ntupleOnDisk.GetSizeCkData());
1392-
memcpy(fileSimple.fShared->fHeaderBlock + fileSimple.fShared->fControlBlock->fSeekNTuple, &ntupleOnDisk,
1393-
ntupleOnDisk.GetSize());
1394-
memcpy(fileSimple.fShared->fHeaderBlock + fileSimple.fShared->fControlBlock->fSeekNTuple + ntupleOnDisk.GetSize(),
1395-
&checksum, sizeof(checksum));
1407+
memcpy(headerBlock + controlBlock->fSeekNTuple, &ntupleOnDisk, ntupleOnDisk.GetSize());
1408+
memcpy(headerBlock + controlBlock->fSeekNTuple + ntupleOnDisk.GetSize(), &checksum, sizeof(checksum));
13961409
fileSimple.Flush();
13971410
return;
13981411
}
@@ -1403,15 +1416,17 @@ void ROOT::Internal::RNTupleFileWriter::Commit(int compression)
14031416
WriteTFileFreeList(); // NOTE: this is written uncompressed
14041417

14051418
// Update header and TFile record
1406-
memcpy(fileSimple.fShared->fHeaderBlock, &fileSimple.fShared->fControlBlock->fHeader,
1407-
fileSimple.fShared->fControlBlock->fHeader.GetSize());
1408-
R__ASSERT(fileSimple.fShared->fControlBlock->fSeekFileRecord +
1409-
fileSimple.fShared->fControlBlock->fFileRecord.GetSize() <
1410-
RImplSimple::kHeaderBlockSize);
1411-
memcpy(fileSimple.fShared->fHeaderBlock + fileSimple.fShared->fControlBlock->fSeekFileRecord,
1412-
&fileSimple.fShared->fControlBlock->fFileRecord, fileSimple.fShared->fControlBlock->fFileRecord.GetSize());
1413-
1414-
fileSimple.Flush();
1419+
if (!fileSimple.fIsClone) {
1420+
memcpy(fileSimple.fShared->fHeaderBlock, &fileSimple.fShared->fControlBlock->fHeader,
1421+
fileSimple.fShared->fControlBlock->fHeader.GetSize());
1422+
R__ASSERT(fileSimple.fShared->fControlBlock->fSeekFileRecord +
1423+
fileSimple.fShared->fControlBlock->fFileRecord.GetSize() <
1424+
RImplSimple::kHeaderBlockSize);
1425+
memcpy(fileSimple.fShared->fHeaderBlock + fileSimple.fShared->fControlBlock->fSeekFileRecord,
1426+
&fileSimple.fShared->fControlBlock->fFileRecord, fileSimple.fShared->fControlBlock->fFileRecord.GetSize());
1427+
1428+
fileSimple.Flush();
1429+
}
14151430
}
14161431

14171432
std::uint64_t ROOT::Internal::RNTupleFileWriter::WriteBlob(const void *data, size_t nbytes, size_t len)

0 commit comments

Comments
 (0)