Bdb packages | Design docs | Source docs | Guidelines | Recent releases

Search | Site Map .

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

/BdbEvent/BdbGenericHdrP.cc

Go to the documentation of this file.
00001 //--------------------------------------------------------------------------
00002 // File and Version Information:
00003 //  $Id: BdbGenericHdrP.cc,v 1.1 1999/04/17 15:08:05 quarrie Exp $
00004 //
00005 // Description:
00006 //  Class BdbGenericHdrP. Implementation file for generic header class.
00007 //
00008 // Environment:
00009 //  Software developed for the BaBar Detector at the SLAC B-Factory.
00010 //
00011 // Author List:
00012 //  David R. Quarrie            Original Author
00013 //
00014 // Copyright Information:
00015 //  Copyright (C) 1994, 1995    Lawrence Berkeley Laboratory
00016 //
00017 // History:
00018 //      Ray F. Cowan 971217    Added binary search on ooTypeNumber and 
00019 //                             linear search for secondary key.  
00020 //      Ray F. Cowan 980114    Use BdbPString objects for secondary key;
00021 //                             no longer add ooTypeN at front of key string.
00022 //      Ray F. Cowan 980202    Fixed use of BdbPString in replace(); treat
00023 //                             secondary key null pointers as null strings.
00024 //
00025 //------------------------------------------------------------------------
00026 
00027 //-----------------------
00028 // This Class's Header --
00029 //-----------------------
00030 #include "BdbEvent/BdbGenericHdrP.hh"
00031 
00032 //-------------
00033 // C Headers --
00034 //-------------
00035 extern "C" {
00036 #include <assert.h>
00037 #include <stddef.h>
00038 #include <string.h>
00039 }
00040 
00041 //---------------
00042 // C++ Headers --
00043 //---------------
00044 #include <iostream.h>
00045 
00046 //-------------------------------
00047 // Collaborating Class Headers --
00048 //-------------------------------
00049 #include "BdbEvent/BdbEventErrors.hh"
00050 #include "BdbUtil/BdbPString.hh"
00051 
00052 //-----------------------------------------------------------------------
00053 // Local Macros, Typedefs, Structures, Unions and Forward Declarations --
00054 //-----------------------------------------------------------------------
00055 
00056 static const char rcsid[] = "$Id: BdbGenericHdrP.cc,v 1.1 1999/04/17 15:08:05 quarrie Exp $";
00057 
00058 //      ----------------------------------------
00059 //      -- Public Function Member Definitions --
00060 //      ----------------------------------------
00061 
00062 //----------------
00063 // Constructors --
00064 //----------------
00065 
00066 BdbGenericHdrP::BdbGenericHdrP( BdbHandle(BdbGenericHdrP)& theHeader )
00067 {
00068     _name = theHeader->name( );
00069      size_t size = theHeader->_data.size( );
00070     _data.resize( size );
00071     _keys.resize( size );
00072     for ( size_t i = 0; i < size; i++ ) {
00073         _data[i] = theHeader->_data[i];
00074         _keys[i] = theHeader->_keys[i];
00075     }
00076 }
00077 
00078 //---------------
00079 // Destructors --
00080 //---------------
00081 
00082 BdbGenericHdrP::~BdbGenericHdrP( )
00083 {
00084     clear( );
00085 }
00086 
00087 //-------------
00088 // Selectors --
00089 //-------------
00090 
00091 const char*
00092 BdbGenericHdrP::name( ) const
00093 {
00094     return (const char*)_name;
00095 }
00096 
00097 d_ULong
00098 BdbGenericHdrP::size( ) const
00099 {
00100     return _data.size( );
00101 }
00102 
00103 d_Boolean
00104 BdbGenericHdrP::isOwner( BdbHandle(BdbPersObj)& theOwner ) const
00105 {
00106     d_Boolean result = false;
00107     if ( theOwner == _owner( ) ) {
00108         result = true;
00109     }
00110     return result;
00111 }
00112 
00113 BdbStatus
00114 BdbGenericHdrP::owner( BdbHandle(BdbPersObj)& theOwner ) const
00115 {
00116     BdbStatus result = BdbcError;
00117     theOwner = 0;
00118     if ( ! BdbIsNull( _owner( ) ) ) {
00119         theOwner = _owner( );
00120         result   = BdbcSuccess;
00121     }
00122     return result;
00123 }
00124 
00125 BdbStatus
00126 BdbGenericHdrP::setOwner( BdbHandle(BdbPersObj)& theOwner )
00127 {
00128     BdbStatus result = update( "BdbGenericHdrP::setOwner" );
00129     set__owner( theOwner ); 
00130     return result;
00131 }
00132 
00133 //--------------
00134 // Operations --
00135 //--------------
00136 
00137 BdbStatus
00138 BdbGenericHdrP::add( const BdbRef(BdbPersObj)& theObj, d_ULong theIndex,
00139                      const char* const theKeyString )
00140 {
00141     // Starting at the rear, bump objects down one, then insert new object
00142     // at the indexed position.
00143 
00144     BdbRef(BdbPersObj) item;
00145     BdbHandle(BdbPString) theKeyH = 0; // These will stay null unless the key
00146     BdbRef(BdbPString) theKey = 0;     // is a non-null string to save time.
00147     BdbRef(BdbPString) itemKey;
00148     BdbRefAny theHint;
00149 
00150     BdbStatus status = _data.update( );
00151     if ( ! status ) {
00152         BdbSignal( BdbcFatalError, BdbEventErrUpdateFailed, 0,
00153            "BdbGenericHdrP::add", "_data.update( )" );
00154     }
00155     assert( status );
00156     status = _keys.update( );
00157     if ( ! status ) {
00158         BdbSignal( BdbcFatalError, BdbEventErrUpdateFailed, 0,
00159            "BdbGenericHdrP::add", "_keys.update( )" );
00160     }
00161     assert( status );
00162 
00163     int theSize = _data.size();
00164 
00165     // Create a new BdbPString object in same container as this tree header,
00166     // but only if the incoming char* string is not a null pointer (equal
00167     // to 0) and is not a null string (a non-null pointer pointing to a
00168     // zero-length char* string).
00169 
00170     if( theKeyString != 0 ) {          // Detect zero pointer.
00171       if( *theKeyString != '\0' ) {    // Detect zero-length char* string.
00172         theHint = ooThis();
00173         theKeyH = new( theHint ) BdbPString( theKeyString );
00174         theKey  = theKeyH;
00175       }
00176     }
00177 
00178     // Now we have either a zero ooRefHandle or a non-zero one accessing a
00179     // non-zero length BdbPString.
00180 
00181     if( theSize == 0 || theIndex == theSize ) {
00182       _data.extend( theObj );
00183       _keys.extend( theKey );
00184     } else {
00185 
00186       int i = 0;
00187       int last = theSize - 1;
00188 
00189       item     = _data[last];
00190       itemKey  = _keys[last];
00191       _data.extend( item    );
00192       _keys.extend( itemKey );
00193 
00194       // cast from d_ULong to int is necessary when i < 0 (eg., "-1 > 0"
00195       // is treated as "4294967295 >= 0" and returns true.
00196       if( theSize > 1 ) for( i = last - 1; i >= (int) theIndex; i-- ) {
00197         item     = _data[i];
00198         itemKey  = _keys[i];
00199         _data.set( i + 1, item    );
00200         _keys.set( i + 1, itemKey );
00201       }
00202 
00203       // Place the new item in the index'ed slot, along with its key.
00204       _data.set( theIndex, theObj );
00205       _keys.set( theIndex, theKey );
00206     }
00207 
00208     return BdbcSuccess;
00209 }
00210 
00211 BdbStatus
00212 BdbGenericHdrP::addItemKey( const BdbRef(BdbPersObj)& theObj, d_ULong theIndex,
00213                             BdbRef(BdbPString)& theKey )
00214 {
00215     // Starting at the rear, bump objects down one, then insert new object
00216     // at the indexed position.
00217 
00218     BdbRef(BdbPersObj) item;
00219     BdbRef(BdbPString) itemKey;
00220     BdbRefAny theHint;
00221 
00222     BdbStatus status = _data.update( );
00223     if ( ! status ) {
00224         BdbSignal( BdbcFatalError, BdbEventErrUpdateFailed, 0,
00225            "BdbGenericHdrP::addItemKey", "_data.update( )" );
00226     }
00227     assert( status );
00228     status = _keys.update( );
00229     if ( ! status ) {
00230         BdbSignal( BdbcFatalError, BdbEventErrUpdateFailed, 0,
00231            "BdbGenericHdrP::addItemKey", "_keys.update( )" );
00232     }
00233     assert( status );
00234 
00235     int theSize = _data.size();
00236 
00237     if( theSize == 0 || theIndex == theSize ) {
00238       _data.extend( theObj );
00239       _keys.extend( theKey );
00240     } else {
00241 
00242       int i = 0;
00243       int last = theSize - 1;
00244 
00245       item     = _data[last];
00246       itemKey  = _keys[last];
00247       _data.extend( item    );
00248       _keys.extend( itemKey );
00249 
00250       // cast from d_ULong to int is necessary when i < 0 (eg., "-1 > 0"
00251       // is treated as "4294967295 >= 0" and returns true.
00252       if( theSize > 1 ) for( i = last - 1; i >= (int) theIndex; i-- ) {
00253         item     = _data[i];
00254         itemKey  = _keys[i];
00255         _data.set( i + 1, item    );
00256         _keys.set( i + 1, itemKey );
00257       }
00258 
00259       // Place the new item in the index'ed slot, along with its key.
00260       _data.set( theIndex, theObj );
00261       _keys.set( theIndex, theKey );
00262     }
00263 
00264     return BdbcSuccess;
00265 }
00266 
00267 BdbStatus
00268 BdbGenericHdrP::get( BdbRef(BdbPersObj)& theItem,
00269                      ooTypeNumber theType,
00270                      const char* const theKeyString ) const
00271 {
00272     BdbRef(BdbPersObj) anItem;
00273     BdbRef(BdbPString) aKey;
00274     BdbHandle(BdbPString) aKeyH;
00275     BdbStatus result = BdbcError;
00276 
00277     int i = 0;
00278     int theSize = size();
00279     if( theSize == 0 ) return result;
00280 
00281     // Implement binary search followed by secondary key string match.
00282     int low  = 0;
00283     int high = theSize - 1;
00284 
00285     i = ( low + high ) / 2;      // initial midpoint
00286 
00287     for(;;) {
00288       item( anItem, i );
00289       if( anItem.typeN() == theType ) {
00290         result = BdbcSuccess;
00291         break;
00292       }
00293 
00294       if( i == high ) {
00295         return result;
00296       }
00297 
00298       if( anItem.typeN() > theType ) { // back up halfway
00299         high = i;
00300       } else { // go forward halfway
00301         low = i;
00302       }
00303 
00304       // reset index and test again
00305       if( ( i == low ) && ( high - low == 1 ) ) {
00306         i = high;
00307       } else {
00308         i = ( low + high ) / 2;
00309       }
00310 
00311     }  // End of for(;;) loop
00312 
00313     // At this point a true result means we have matched the TypeN but
00314     // not necessarily the secondary key.  Now do a linear search from
00315     // the current position back and forward of matching TypeN's.
00316 
00317     // Store the key string as an BdbTString.  This will create a BdbTString
00318     // object representing a zero-length string if either theKeyString is a
00319     // zero pointer, or if it is a valid pointer to a zero-length string.
00320     // Otherwise it creates a non-null BdbTString object.
00321     BdbTString theName = theKeyString;
00322 
00323     // Reset success flag
00324     result = BdbcError;
00325     int start = i;
00326 
00327     // Handle required for scoping object
00328     BdbHandle(BdbGenericHdrP) thisH;
00329     thisH = ooThis();
00330     getKey( aKeyH, start ); // Use handle to allow * operation
00331 
00332     // min and max ooVArray limits
00333     const int bottom = 0;
00334     const int top = theSize - 1;
00335 
00336     // Search backward
00337     while( ( i >= bottom ) && ( anItem.typeN() == theType ) ) {
00338       if( aKeyH != 0 ) {  // valid handle, can perform comparison
00339         if( theName == *aKeyH ) {
00340           theItem = anItem;
00341           result = BdbcSuccess;
00342           break;
00343         }
00344       } else {  // zero handle implies null string
00345         if( theName == "" ) {  // check for null only
00346           theItem = anItem;
00347           result = BdbcSuccess;
00348           break;
00349         }
00350       }
00351       i--;
00352       if( i < bottom ) break;
00353       item  ( anItem, i );
00354       getKey( aKeyH,  i ); // Use handle to allow * operation
00355     }
00356 
00357     i = ++start;
00358     if( i <= top ) {
00359       item  ( anItem, i );
00360       getKey( aKeyH,  i ); // Use handle to allow * operation
00361     }
00362 
00363     // Search forward
00364     if( !result ) while( ( i <= top ) && ( anItem.typeN() == theType ) ) {
00365       if( aKeyH != 0 ) {  // valid handle, can perform comparison
00366         if( theName == *aKeyH ) {
00367           theItem = anItem;
00368           result = BdbcSuccess;
00369           break;
00370         }
00371       } else {  // zero handle implies null string
00372         if( theName == "" ) {  // check for null only
00373           theItem = anItem;
00374           result = BdbcSuccess;
00375           break;
00376         }
00377       }
00378       i++;
00379       if( i > top ) break;
00380       item  ( anItem, i );
00381       getKey( aKeyH,  i ); // Use handle to allow * operation
00382     }
00383 
00384     return result;
00385 }
00386 
00387 BdbStatus
00388 BdbGenericHdrP::getItem( BdbRef(BdbPersObj)& theItem,
00389                          d_ULong index ) const
00390 {
00391     BdbStatus result = BdbcError;
00392 
00393     int theSize = size();
00394     if( theSize == 0 ) return result;
00395     if( index > theSize - 1 ) return result;
00396 
00397     result = item( theItem, index );
00398     return result;
00399 }
00400 
00401 BdbStatus
00402 BdbGenericHdrP::getKey( BdbHandle(BdbPString)& theKey, d_ULong theIndex ) const
00403 {
00404     d_Boolean result = BdbcSuccess;
00405     theKey = _keys[theIndex];
00406     return result;
00407 }
00408 
00409 BdbStatus
00410 BdbGenericHdrP::getKey( BdbRef(BdbPString)& theKey, d_ULong theIndex ) const
00411 {
00412     d_Boolean result = BdbcSuccess;
00413     theKey = _keys[theIndex];
00414     return result;
00415 }
00416 
00417 BdbStatus
00418 BdbGenericHdrP::item( BdbRef(BdbPersObj)& theItem, d_ULong theIndex ) const
00419 {
00420     BdbStatus result = BdbcSuccess;
00421     theItem = _data[theIndex];
00422     return result;
00423 }
00424 
00425 BdbStatus
00426 BdbGenericHdrP::put( BdbRef(BdbPersObj)& theObj, const char* const theKeyString )
00427 {
00428     ooTypeNumber theType = theObj.typeN();
00429     BdbRef(BdbPersObj) anItem( 0 );
00430     BdbRef(BdbPString) aKey;
00431     BdbHandle(BdbPString) aKeyH;
00432     BdbRef(BdbPersObj) highItem( 0 );
00433 
00434     BdbStatus status = _data.update( );
00435     if ( ! status ) {
00436         BdbSignal( BdbcFatalError, BdbEventErrUpdateFailed, 0,
00437            "BdbGenericHdrP::put", "_data.update( )" );
00438     }
00439     assert( status );
00440     status = _keys.update( );
00441     if ( ! status ) {
00442         BdbSignal( BdbcFatalError, BdbEventErrUpdateFailed, 0,
00443            "BdbGenericHdrP::put", "_keys.update( )" );
00444     }
00445     assert( status );
00446 
00447     int i = 0;
00448     int theSize = size( );
00449 
00450     // Perform binary sort on insertion
00451     int low = 0;
00452     int high = theSize - 1;
00453     i = ( low + high ) / 2;
00454 
00455     // min and max ooVArray limits
00456     const int bottom = 0;
00457     const int top = theSize - 1;
00458 
00459     // Store the key string as an BdbTString.  This will create a BdbTString
00460     // object representing a zero-length string if either theKeyString is a
00461     // zero pointer, or if it is a valid pointer to a zero-length string.
00462     // Otherwise it creates a non-null BdbTString object.
00463     BdbTString theName = theKeyString;
00464 
00465     if( theSize > 0 ) {
00466       for(;;) {
00467         item( anItem, i );
00468 
00469         if( anItem.typeN() == theType ) {
00470 
00471           // Now search back/forward for key match, if any.  If no match is
00472           // found, we add it; if a match is found, we assert an error.
00473 
00474           int j = i;
00475           int start = j; // record start position for later upward search
00476 
00477           getKey( aKeyH, j ); // Use handle to allow * operation
00478 
00479           // Search backward
00480           while( ( j >= bottom ) && ( anItem.typeN() == theType ) ) {
00481             if( aKeyH != 0 ) {  // valid handle, can perform comparison
00482               status = ( theName != *aKeyH );
00483             } else {  // zero handle implies null string
00484               status = ( theName != "" );
00485             }
00486             if ( !status ) {
00487               BdbSignal( BdbcFatalError, BdbEventErrObjectCollision, 0,
00488                          "BdbGenericHdrP::put", theObj.typeName(),
00489                          theName.data(), name() );
00490             }
00491             assert( status );
00492             j--;
00493             if( j < bottom ) break;
00494             item  ( anItem, j );
00495             getKey( aKeyH, j ); // Use handle to allow * operation
00496           }
00497 
00498           j = ++start;
00499           if( j <= top ) {
00500             item  ( anItem, j );
00501             getKey( aKeyH, j ); // Use handle to allow * operation
00502           }
00503 
00504           // Search forward
00505           while( ( j <= top ) && ( anItem.typeN() == theType ) ) {
00506             if( aKeyH != 0 ) {  // valid handle, can perform comparison
00507               status = ( theName != *aKeyH );
00508             } else {  // zero handle implies null string
00509               status = ( theName != "" );
00510             }
00511             if ( !status ) {
00512               BdbSignal( BdbcFatalError, BdbEventErrObjectCollision, 0,
00513                          "BdbGenericHdrP::put", theObj.typeName(),
00514                          theName.data(), name() );
00515             }
00516             assert( status );
00517             j++;
00518             if( j > top ) break;
00519             item  ( anItem, j );
00520             getKey( aKeyH, j ); // Use handle to allow * operation
00521           }
00522 
00523           // Item not in array: type number matched, but not secondary key,
00524           // so add it here
00525           add( theObj, i, theName );
00526           break;
00527         }
00528 
00529         if( i == high ) {
00530           // Item not in array: no type number match, so add it here
00531           if( anItem.typeN() > theType ) {
00532             add( theObj, i, theName );
00533           } else {
00534             add( theObj, i+1, theName );
00535           }
00536           break;
00537         }
00538 
00539         if( anItem.typeN() > theType ) {
00540           // back up halfway
00541           high = i;
00542         } else {
00543           // advance halfway
00544           low = i;
00545         }
00546 
00547         // reset index and test again
00548         if( ( i == low ) && ( high - low == 1 ) ) {
00549           i = high;
00550         } else {
00551           i = ( low + high ) / 2;
00552         }
00553 
00554       } //  end of for{;;}
00555     } // end of if( theSize > 0 )
00556     else { // No elements yet: theSize is zero
00557       add( theObj, 0, theName );
00558     }
00559     return BdbcSuccess;
00560 }
00561 
00562 void
00563 BdbGenericHdrP::clear( d_Boolean destroyItems )
00564 {
00565     BdbHandleAny theItem;
00566     BdbHandle(BdbPString) theKey;
00567     BdbStatus status = update( "BdbGenericHdrP:clear" );
00568     d_ULong nKeys = _keys.size( );
00569     d_ULong iKey;
00570     for ( iKey = 0; iKey < nKeys; iKey++ ) {
00571         theKey = _keys[iKey];
00572         if ( ! BdbIsNull( theKey ) ) {
00573             BdbDelete( theKey );
00574             _keys[iKey] = 0;
00575             if ( destroyItems ) {
00576                 theItem = _data[iKey];
00577                 BdbDelete( theItem );
00578             }
00579             _data[iKey] = 0;
00580         }
00581     }
00582     _keys.resize( 0 );
00583     _data.resize( 0 );
00584 }
00585 
00586 void
00587 BdbGenericHdrP::clearAndDestroy( )
00588 {
00589     clear( d_True );
00590 }
00591 
00592 //      -------------------------------------------
00593 //      -- Protected Function Member Definitions --
00594 //      -------------------------------------------
00595 
00596 //----------------
00597 // Constructors --
00598 //----------------
00599 
00600 BdbGenericHdrP::BdbGenericHdrP( const char* const theName )
00601 {
00602     _name = theName;
00603 }
00604 
00605 BdbGenericHdrP::BdbGenericHdrP( BdbHandle(BdbPersObj)& theOwner, 
00606                                 const char* const theName )
00607 {
00608     _name = theName;
00609     set__owner( theOwner ); 
00610 }
00611 
00612 //--------------
00613 // Operations --
00614 //--------------
00615 
00616 BdbStatus
00617 BdbGenericHdrP::update( const char* const location )
00618 {
00619     BdbStatus result = ooUpdate( );
00620     if ( ! result ) {
00621         BdbSignal( BdbcFatalError, BdbEventErrObjUpdateFailed, 0, 
00622            "BdbGenericHdrP::update", location );
00623     }
00624     return result;
00625 }
00626 

 


BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us

Page Owner: Jacek Becla
Last Update: October 04, 2002