On Thu, 28 Oct 1999, Rene Brun wrote: > > As far as I understand, the normal procedure for ROOT when reading objects > > e.g. of type A in a TObjectBranch of a TTree is to delete the previous > > object pointed to by the pointer contained in TObjectBranch::fAddress and > > creating a new object using its default ctor A::A(). Then it is filled > > using the Streamer member function of the object A::Streamer(...). > > This will work if users make sure to delete all objects and basic types > allocated via new in the Streamer function itself. I cannot introduce > this functionality by default, too many people will complain. > However, I could introduce an option (at the branch or tree ? level) > to tell Root that it should not delete the object before invoking > Streamer. > What about TTree:SetAutoDelete(Bool_t mode=kTRUE) ? That sounds good, but I think it should also be possible to set this per branch. So TTree::SetAutoDelete(Bool_t mode=kTRUE) could be used to set the default behaviour for all branches of a tree, but one could also use TBranch::SetAutoDelete(Bool_t mode=kTRUE) to switch branches individually. One could also think of a scheme, where it depends on the value of the pointer in TBranch::fAddress, e.g. if it is 0, ROOT creates and deletes for every event, and if it is != 0, ROOT doesn't does not delete and create it. However, I do not like this implicit method, and I prefer explicit setting of this important behaviour in the way you proposed. > Note that in case of split mode, this is already the case. The top level > object is never deleted. Oops, I didn't realise this. This is another example of behaviour differences between branches in split-mode and non-split-mode, I guess. (The other one was that the pointer to the read object was not available via the pointer in TBranch::fAddress, and has been fixed in 2.23/04). It seems these two behaviour differences are connected, since in split-mode ROOT does not delete the object it was presumed not neccessay to provide the pointer through TBranch::fAddress. It would be preferable to have the same behaviour of branches in split- or non-split-mode, i.e. setting the split mode should not have side-effects (other than creating lots of branches of course!). I assume that some existing code might be broken, if ROOT changes its default behaviour for split-mode branches from not deleting objects to deleting them. I personally would prefer to have consistent default behaviour for all branches, at least after TTree::SetAutoDelete(true/false) has been called. Perhaps the general default should be, that objects are not deleted, but this could introduce new memory leaks in existing user code. > > Is it possible to arrange it so that ROOT does not delete the existing > > object, and just calls the Streamer A::Streamer again to overwrite the > > contents? > > > > This should work ok for objects with "constant memory footprint", i.e. > > those which don't allocate memory from the heap themselves. > > > > One interesting application would be that one could have several > > TObjectBranch'es holding the *same* type of objects, which in turn contain > > non-static pointers to TClonesArrays holding identical types of objects. > > I am not sure I understand what you mean precisely without giving an > example. Your suggestion above answers my question. > > Currently, one can only have one TObjectBranch containig objects with > > a static pointer to one TClonesArray to reuse memory. If one would have > > several branches, reading the next branch would overwrite the data from a > > previously read branch in the one shared TClonesArray. > > > > > For example, one could read several TObjectBranches of the Event > > class containig different events. Of course, one would not do this with an > > "event", but one could imagine storing and retrieving several objects of > > the same type containg lists of e.g. tracks reconstructed in different > > ways. > \ > You can already do this by either swapping pointers or calling > tree->SetBranchAddress. I think you suggest ways to reuse one object in several branches. But what about the case, when I need the data of both branches simultaneously, i.e. I really need two objects including two TClonesArrays in memory? If I was guaranteed that the top level object does not get deleted, it could hold a non-static pointer to a TClonesArray, which would be reused for just this branch. Your nice suggestion above would allow exactly this solution, and decouple it from using split-mode. I would have another suggestion for a convenience to users of objects, which don't get deleted. These must be "cleared" after every event, if they allocate memory or contain a pointer to a TClonesAyrray. Adding a new virtual member function to TObject might make this easier: class TObject { ... public: virtual Clear() {} ... } A user could implement Clear() to do the cleaning up if neccessary and TBranch would call it always just before actually reading a new entry (if it is in the state that it does not delete/create objects for every entry, a default or from calling TTree::SetAutoDelete(false) or TBranch::SetAutoDelete(false)). cheers, Stefan ---Stefan Kluth---------------Lynen Fellow----------------|\--|\------- - LBNL, MS 50A 2160 - phone: +1 510 495 2376 - |/ |/ - - 1 Cyclotron Rd. - fax: +1 510 495 2957 - |\/\|\/\|' - ---Berkeley, CA94720, USA-----e-mail: SKluth@lbl.gov------|/\/|/\/|----
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:41 MET