Pasha, I am sure that you know the answer to your question ::) Just declare: TClonesArray* fArray; //-> The "->" in the comment field instructs ROOT that it can assume that fArray always exists and points to a valid object. In this case, the system will automatically clear the array before a new read. Rene Brun On Thu, 8 Nov 2001, Pasha Murat (630)840-8237@169G wrote: > 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:07 MET