Skip to content

Conversation

silverweed
Copy link
Contributor

@silverweed silverweed commented Oct 8, 2025

Followup of #19958. Other than addressing @pcanal's comments, this PR introduces the ListKeys() method, which iterates over the keys of some subdirectory.
They do so via an iterator that returns an abridged version of TKey, currently containing only barebones information (more may be added later).

Checklist:

  • tested changes locally
  • updated the docs (if necessary)

Copy link

github-actions bot commented Oct 8, 2025

Test Results

    19 files      19 suites   3d 8h 51m 22s ⏱️
 3 688 tests  3 687 ✅ 0 💤 1 ❌
68 375 runs  68 370 ✅ 0 💤 5 ❌

For more details on these failures, see this check.

Results for commit d4daafe.

♻️ This comment has been updated with latest results.

@silverweed silverweed force-pushed the rfile_02 branch 3 times, most recently from ed31e98 to a001f6d Compare October 8, 2025 15:00
Querying this information can be done via RFile::GetKeys() or RFile::GetKeysNonRecursive. Reading an object's Key
doesn't deserialize the full object, so it's a relatively lightweight operation.
*/
struct RFileKeyInfo {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure this is the best name, because the keys are the same whether it is TFile or RFile. I'd probably prefer RFile::RKeyInfo or Detail::RKeyInfo... (not entirely sure about those two either).

@silverweed silverweed changed the title [rfile] Introduce GetKeys() methods [rfile] Introduce ListKeys() method Oct 9, 2025
throw ROOT::RException(R__FAIL("failed to open file " + std::string(path) + " for reading"));

if (tfile->IsRaw() || !tfile->IsBinary() || tfile->IsArchive())
throw ROOT::RException(R__FAIL("Opened file " + std::string(path) + " is not a ROOT file"));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
throw ROOT::RException(R__FAIL("Opened file " + std::string(path) + " is not a ROOT file"));
throw ROOT::RException(R__FAIL("Opened file " + std::string(path) + " is not a ROOT binary file"));

whether we want to hint on whether xml and archive file will be supported at some point is another question.

throw ROOT::RException(R__FAIL("failed to open file " + std::string(path) + " for updating"));

if (tfile->IsRaw() || !tfile->IsBinary() || tfile->IsArchive())
throw ROOT::RException(R__FAIL("Opened file " + std::string(path) + " is not a ROOT file"));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
throw ROOT::RException(R__FAIL("Opened file " + std::string(path) + " is not a ROOT file"));
throw ROOT::RException(R__FAIL("Opened file " + std::string(path) + " is not a ROOT binary file"));

throw ROOT::RException(R__FAIL("failed to open file " + std::string(path) + " for writing"));

if (tfile->IsRaw() || !tfile->IsBinary() || tfile->IsArchive())
throw ROOT::RException(R__FAIL("Opened file " + std::string(path) + " is not a ROOT file"));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
throw ROOT::RException(R__FAIL("Opened file " + std::string(path) + " is not a ROOT file"));
throw ROOT::RException(R__FAIL("Opened file " + std::string(path) + " is not a ROOT binary file"));

Comment on lines +51 to +54
std::string fName;
std::string fTitle;
std::string fClassName;
std::uint16_t fCycle = 0;
Copy link
Member

Choose a reason for hiding this comment

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

Here we choose to duplicate the information rather than forwarding it from the live TKey. What are the pros and cons?

(since they are a concept in the ROOT binary format). However they are for now only interacted with indirectly, via the
use of filesystem-like string-based paths. If you Put an object in an RFile under the path "path/to/object", "object"
will be stored under directory "to" which is in turn stored under directory "path". This hierarchy is encoded in the
ROOT file itself and it can provide some optimization and/or conveniencies when querying objects.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
ROOT file itself and it can provide some optimization and/or conveniencies when querying objects.
ROOT file itself and it can provide some optimization and/or conveniences when querying objects.

/// Flushes the RFile if needed and closes it, disallowing any further reading or writing.
void Close();

/// Returns an iterable over all paths of objects written into this RFile starting at path "rootPath".
Copy link
Member

Choose a reason for hiding this comment

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

The sentence does not give wiggle room to include the case (flags & kListRecursive) == 0. We should add a conditional somewhere, for example

Suggested change
/// Returns an iterable over all paths of objects written into this RFile starting at path "rootPath".
/// Returns an iterable over all paths of objects written into this RFile starting at path "rootPath" (defaulting to also include the content of sub-directories)

(but the proposed words don't seem to match the first part (path vs directories))


// Reconstruct the full path of the key
const auto &fullPath = dirPath + dirSep + key->GetName();
const auto nesting = fIterStack.size() - 1;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const auto nesting = fIterStack.size() - 1;
const std::uint16_t nesting = fIterStack.size() - 1;

To avoid the warnings:

comparison of integer expressions of different signedness: ‘const long unsigned int’ and ‘int’ [-Wsign-compare]

Alternatively fRootDirNesting could be made the same as decltype(fIterStack.size())

if (!tfile || tfile->IsZombie())
throw ROOT::RException(R__FAIL("failed to open file " + std::string(path) + " for reading"));

if (tfile->IsRaw() || !tfile->IsBinary() || tfile->IsArchive())
Copy link
Member

Choose a reason for hiding this comment

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

Why is RFile sensitive to the backend (binary vs text) used by TFIle?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants