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