Hi Rene, and what happens in a particular case when MyObject contains a pointer to a TClonesArray with large number of elements? class MyObject: public TObject { .. TClonesArray* fArray; ... }; I saw in the past that in case above recreation of a long TClonesArray for every new event was introducing a HUGE I/O performance penalty, so I was trying to use SetAutoDelete where appropriate. If this option has no effect any longer, would you advise to start getting rid of "*" in "TClonesArray*" or what is the right solution for split mode? - I presume that in non-split mode one can use [custom] Streamers to take care of this issue. thanks, Pasha Rene Brun wrote: > > Hi Thomas, > > Since the introduction of the new branch style (TBranchElement), the default > in versions 3.01 and 3.02, SetAutoDelete is not required anymore and it > is ignored. This process is now automatic. > > Suppose you have a branch with > MyClass *MyObject = 0; > tree.SetBranchAddress("bname",&MyObject); > > When calling tree.GetEntry(), if MyObject is null, a new instance of MyClass > is created, otherwise the previous object is replaced by the new data. > If MyObject has pointers to other objects (may be collections), > these objects are automatically deleted recreated and filled with the new data. > If MyClass contains only basic types or objects that in turn contain only basic > types, no constructors need to be called-> an appreciable gain in time. > > In your loop calling GetEntry, you can add a statement > delete MyObject; MyObject = 0; > to force a call to your destructor. If GetEntry finds a null pointer, it will > automatically call the default MyClass constructor. > > In case of TChains, SetAutoDelete was never taken into account. > I did not implement it for the new branch styles since it is redundant. > > Rene Brun > > Thomas Bretz wrote: > > > > Hi Rene, > > > > if I understood you correctly code like : > > ---------- > > TFile file(...); > > MyObj *myobjptr = new MyObj; > > file->Get("Tree")->GetBranch("branch")->SetAutoDelete(); > > file->Get("Tree")->GetBranch("branch")->SetAdress(&myobjectptr); > > for (int i=0; i<100; i++) file->Get("Tree")->GetEntry(i); > > ---------- > > should result in a call to ~MyObj every time a new event is read. But in > > my case SetAutoDelete is completely ignored: > > ---------- > > TChain chain("Tree"); > > chain.Add("file.root"); > > MyObj *myobjptr = new MyObj; > > chain.GetBranch("branch")->SetAutoDelete(); > > chain.SetBranchAddress("branch", &myobjectptr); > > for (int i=0; i<100; i++) chain.GetEntry(i); > > ---------- > > does only result in _one_ call to the destructor of MyObj. That's the > > problem. > > > > In my opinion the problem is due to the fact that when LoadTree switches > > files (also from no file to the first file) the information stored in > > TBranch (set via TBranch::SetAutoDelete()) is lost. Maybe I'm wrong. > > > > Thomas. > > > > > > I'm using a TChain to access my tree and its branches. I was wondering, > > > > why the destructors of my functions are not called independant of the > > > > Setting of TChain::GetBranch->SetAutoDelete. From a look at the code of > > > > TChain::GetEntry/LoadTree it seems to me, that the setting of the > > > > autodelete flag is skipped at least when a new File is opened and the > > > > TChainElement settings are copied to the TBranch of the new file. Am I > > > > right, or was the way of setting these flag incorrect?
This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:51:06 MET