Re: split/non-split difference in SetAddress()

From: Rene Brun (Rene.Brun@cern.ch)
Date: Fri Sep 17 1999 - 15:18:42 MEST


Following this original mail by Andy Salnikov, we had some exchange of
mails. Andy convinced me that his proposal was very interesting.
In addition the implementation was trivial (one additional line
in TBranchObject::SetAddress).
With Root version 2.23, there is a symmetry between split and no-split
mode.

I would like to thank Andy for this nice suggestion.

Rene Brun


Andrei Salnikov wrote:
> 
> Hi all,
> 
> I'm stuck with one of the SetAddress() features of the TBranchObject. I'm
> trying to implement what may be called a "schema evolution". Idea, which
> worked nice with other persistent data stores, is rather simple - for each
> new version of the persistent data we create a separate class definition
> with different name. So for each persistent data item we have a number of
> persitent classes (e.g. ClassA_001, ClassA_002, etc.) which have a common
> base class (say ClassBaseA) defining an interface sufficient for dealing
> with the data. As the schema evolves we have different trees having
> different concrete classes. Dealing with this in universal approach means
> accessing data in the tree throught the common base class. . This implies
> that we cannot allocate memory for the objects, as we do not know concrete
> type of the objects, ROOT should do it instead. Wery nice, I tried something
> like that:
> 
> //    Reader.h
> class Reader {
>    // ......
>    ClassBaseA* theObjectPointer_ ;
> };
> 
> // Reader.cc
> ClassBaseA*
> Reader::read( int eventIndex )
> {
>    if ( address_is_not_set_yet ) {
>       theObjectPointer_ = 0 ;
>       theBranch_ -> SetAddress ( (void*)(&theObjectPointer_) ) ;
>       say_address_is_set_now() ;
>    }
>    int nbytes = theBranch_ -> GetEntry( eventIndex ) ;
> 
>    return nbytes>0 ? theObjectPointer_ : 0 ;   // return null if no success
> }
> 
> It worked OK for objects written in non-split mode but failed read objects
> written in split mode. Although it did not fail completely - GetEntry()
> returned numbers grater that 0, but it did not set theObjectPointer_ to any
> value - the pointer remained 0 all the time. After digging in the ROOT code
> I was able to conclude that it really works in that way - when calling
> SetAddress() with pointer set to 0 for branch written in split mode, it
> creates an object internaly and all later reads put the data in that
> internal object, without passing pointer to this object back to the user.
> For the branches written in non-split mode situation is somewhat different
> (why?) - it creates new object for every read operation and changes the
> pointer so that it points to this new object. I can't really understand why
> is this difference in approaches, does it really must be like that? Can't we
> make the behavior more uniform across split and non-split branches?
> 
>   Cheers,
>   Andy.



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:39 MET