ROOT records w/ sub-dirs

hi there,

I am a bit puzzled by the output of this ROOT macro:

void subdirs_root() {
	auto f = TFile::Open("subdirs.root", "RECREATE");
	auto dir1 = f->mkdir("dir-1");      dir1 ->cd();
	auto dir11 = dir1->mkdir("dir-11"); dir11->cd();
	auto obj = new TObjString("data-obj1");

	auto dir2 = f->mkdir("dir-2"); dir2->cd();
	auto obj2 = new TObjString("data-obj2");

	f->Write(); f->Close();


using root-ls (from groot) after having executed that macro above, I get:

$> root-ls ./subdirs.root
=== [./subdirs.root] ===
version: 61804
TDirectoryFile   dir-1   dir-1                    (cycle=1)
  TDirectoryFile dir-11  dir-11                   (cycle=1)
    TObjString   obj1    Collectable string class (cycle=1)
TDirectoryFile dir-2   dir-2                    (cycle=1)
  TObjString   obj2    Collectable string class (cycle=1)

which seems reasonable.

and the output of executing TFile::Map() on that ROOT file is:

20191008/180105  At:100    N=144       TFile         
20191008/180105  At:244    N=109       TDirectory    // -> "dir-1"
20191008/180105  At:353    N=111       TDirectory    // -> "dir-11"
20191008/180105  At:464    N=93        TObjString    // -> "obj1"
20191008/180105  At:557    N=109       TDirectory    // -> "dir-2"
20191008/180105  At:666    N=93        TObjString    // -> "obj2"
20191008/180105  At:759    N=122       TDirectory    // -> "dir-11"
20191008/180105  At:881    N=104       TDirectory    // -> "dir-1"
20191008/180105  At:985    N=120       TDirectory    // -> "dir-2"
20191008/180105  At:1105   N=160       KeysList      
20191008/180105  At:1265   N=281       StreamerInfo   CX =  1.54
20191008/180105  At:1546   N=68        FreeSegments  
20191008/180105  At:1614   N=1         END           

(I have added the name of the associated key)
there are duplicates, but ok (?).

but inspecting the fSeekXXX values of the directories leads to something peculiar:

>>> import ROOT
>>> f = ROOT.TFile.Open("./subdirs.root")

>>> dir1 = f.Get("dir-1")
>>> dir1.GetSeekDir()
>>> dir1.GetSeekParent()
100 ## ok.

>>> dir11 = dir1.Get("dir-11")
>>> dir11.GetSeekDir()
>>> dir11.GetSeekParent()
100 ## ???

ie: the sub dir dir-11 has as an on-disk parent the “root” directory instead of the expected "dir-1" one.
at least, that’s my understanding of this diagram:

(this threw me off when trying to implement nested sub-directories in groot.)

So, why is the fSeekParent field of directories and sub-directories always TFile::fBegin ?
(and why are there duplicates TDirectories ? they do not seem to be GAPs nor deleted keys…)


ROOT Version: 6.18/04
Platform: linuxx8664gcc
Compiler: gcc (GCC) 9.2.0

replace f->Write(); f->Close(); with delete f;

thanks, but I get the same (kind of) output:

>>> import ROOT
>>> f=ROOT.TFile.Open("subdirs.root")
>>> f.Map()
20191008/200126  At:100    N=144       TFile         
20191008/200126  At:244    N=109       TDirectory    
20191008/200126  At:353    N=111       TDirectory    
20191008/200126  At:464    N=93        TObjString    
20191008/200126  At:557    N=109       TDirectory    
20191008/200126  At:666    N=93        TObjString    
20191008/200126  At:759    N=281       StreamerInfo   CX =  1.54
20191008/200126  At:1040   N=160       KeysList      
20191008/200126  At:1200   N=104       TDirectory    
20191008/200126  At:1304   N=122       TDirectory    
20191008/200126  At:1426   N=120       TDirectory    
20191008/200126  At:1546   N=68        FreeSegments  
20191008/200126  At:1614   N=1         END    
>>> dir11 = f.Get("dir-1").Get("dir-11")       
>>> dir11.GetSeekParent()
>>> dir11.GetSeekDir()

Hi Sebastien,

Indeed, fSeekParent has been pointing to the top level directory in the file (aka the “root” directory) since the very beginning :frowning: . We probably should update the code to match the documentation :slight_smile:

(and why are there duplicates TDirectories ? they do not seem to be GAPs nor deleted keys…)

They are not duplicate. The information for TDirectory is stored in 2 parts. One fixed length (for a given directory name) that contains only meta data (name, location of the 2nd part, unique id, etc.) and a second one of variable length containing the TKey meta information for the directory.



I have created to not forget about this.
(so I can implement the same thing in groot when it lands in ROOT)

thanks Philippe.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.