Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions tree/ntuple/inc/ROOT/RNTupleProcessor.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -615,9 +615,8 @@ private:
/// \brief Get the total number of entries in this processor.
ROOT::NTupleSize_t GetNEntries() final
{
Initialize();
if (fNEntries == ROOT::kInvalidNTupleIndex)
Connect(fFieldIdxs);
Initialize();
return fNEntries;
}

Expand Down
15 changes: 13 additions & 2 deletions tree/ntuple/src/RNTupleProcessor.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -347,13 +347,24 @@ ROOT::Experimental::RNTupleChainProcessor::AddFieldToEntry(const std::string &fi

ROOT::NTupleSize_t ROOT::Experimental::RNTupleChainProcessor::LoadEntry(ROOT::NTupleSize_t entryNumber)
{
ROOT::NTupleSize_t localEntryNumber = entryNumber;
std::size_t currProcessorNumber = 0;
// If the requested entry number is lower than the current entry number, we have to again localise the correct local
// entry number starting from the first processor in the chain. Otherwise, we can continue looking from the inner
// processor that is currently connected, which is much faster when the chain consists of many inner processors.
if (entryNumber < fCurrentEntryNumber) {
Comment on lines +350 to 353

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can't this be speed up in case the entryNumber is less than the fCurrentEntryNumber but more than the starting entry number of the current file? (and/or is the set of lengths cached and thus fast to go through again?)

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.

Yes, the set of lengths is cached:

for (unsigned i = 0; i < currProcessorNumber; ++i) {
if (fInnerNEntries[i] == kInvalidNTupleIndex) {
fInnerNEntries[i] = fInnerProcessors[i]->GetNEntries();
}
entriesSeen += fInnerNEntries[i];
}

fCurrentProcessorNumber = 0;
ConnectInnerProcessor(fCurrentProcessorNumber);
}

std::size_t currProcessorNumber = fCurrentProcessorNumber;
ROOT::NTupleSize_t entriesSeen = 0;
for (unsigned i = 0; i < currProcessorNumber; ++i) {
if (fInnerNEntries[i] == kInvalidNTupleIndex) {
fInnerNEntries[i] = fInnerProcessors[i]->GetNEntries();
}
entriesSeen += fInnerNEntries[i];
}
Comment on lines +358 to +365

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not for this PR, but in principle we could have a cache vector of number of entries per processor which is filled lazily at discovery time whenever a processor needs to connect to file(s)

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.

Actually this is exactly what is done a few lines down and somehow didn't think to do it here, so thanks for pointing this out :D. Let me quickly add it here as well.

ROOT::NTupleSize_t localEntryNumber = entryNumber - entriesSeen;

// As long as the entry fails to load from the current processor, we decrement the local entry number with the number
// of entries in this processor and try with the next processor until we find the correct local entry number.
while (fInnerProcessors[currProcessorNumber]->LoadEntry(localEntryNumber) == kInvalidNTupleIndex) {
Expand Down
Loading