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

CdbBdbSCollectionP.cc

Go to the documentation of this file.
00001 // File and Version Information:
00002 //      $Id: CdbBdbSCollectionP.cc,v 1.10 2004/08/06 05:54:24 bartoldu Exp $
00003 
00004 /// Implementation file for the CdbBdbSCollectionP class.
00005 /**
00006   * @see CdbBdbSCollectionP
00007   */
00008 
00009 #include "BaBar/BaBar.hh"
00010 
00011 #include "CdbBdbShared/CdbBdbSCollectionP.hh"
00012 
00013 #include "CdbBdbShared/CdbBdbSCollectionElementP.hh"
00014 #include "CdbBdbShared/CdbBdbSCollectionIdItr.hh"
00015 #include "CdbBdbShared/CdbBdbSCollectionNameItr.hh"
00016 
00017 #include <assert.h>
00018 using std::cout;
00019 using std::endl;
00020 using std::ostream;
00021 
00022 CdbBdbSCollectionP::CdbBdbSCollectionP( bool useIdFlag,
00023                                         bool useNameFlag ) :
00024     _treeRef(0),
00025     _mapRef(0),
00026     _elements(0)
00027 {
00028     assert( useIdFlag || useNameFlag );     // CONFIGURATIN ERROR - AT LEAST ONE WAY
00029                                             // TO IDENTIFY COLLECTION ELEMENTS IS EXPECTED
00030 
00031     if( useIdFlag   ) _treeRef = new( ooThis( )) BTreeP( );
00032     if( useNameFlag ) _mapRef  = new( ooThis( )) BdbMap( );
00033 }
00034 
00035 CdbBdbSCollectionP::~CdbBdbSCollectionP( ) 
00036 {
00037   // Remove all the elements first
00038   //
00039   // NOTE: The preferable way of removing elements is through the B-tree.
00040   //       However if the identifiers are not used in the current configuration
00041   //       then we should use ooMap.
00042 
00043     if( ! BdbIsNull( _treeRef )) {
00044 
00045         CdbItr< BTreeEntry > itr = _treeRef->iterator( );
00046         while( itr.next( )) {
00047             BTreeEntry e = itr.value( );
00048             BdbDelete( e.value );
00049         }
00050 
00051     } else {
00052 
00053         assert( ! BdbIsNull(_mapRef));
00054 
00055         ooMapItr itr( _mapRef );
00056         while( itr.next( )) {
00057             BdbRef( CdbBdbSCollectionElementP ) eRef;
00058             eRef = (const BdbRef( CdbBdbSCollectionElementP )&) (itr->oid( ));
00059             BdbDelete( eRef );
00060         }
00061     }
00062 
00063   // Remove the rest
00064 
00065     if( ! BdbIsNull( _treeRef )) BdbDelete( _treeRef );
00066     if( ! BdbIsNull( _mapRef  )) BdbDelete( _mapRef );
00067 }
00068 
00069 bool
00070 CdbBdbSCollectionP::useId( ) const
00071 {
00072     return ! BdbIsNull( _treeRef );
00073 }
00074 
00075 bool
00076 CdbBdbSCollectionP::useName( ) const
00077 {
00078     return ! BdbIsNull( _mapRef );
00079 }
00080 
00081 d_ULong
00082 CdbBdbSCollectionP::elements( ) const
00083 {
00084     return _elements;
00085 }
00086 
00087 CdbStatus
00088 CdbBdbSCollectionP::insert( const BdbRef( CdbBdbSCollectionElementP )& theRef )
00089 {
00090     const char* errorStr = "CdbBdbSCollectionP::insert() -- ERROR";
00091 
00092     ooUpdate( );
00093 
00094     CdbStatus result = CdbStatus::Error;
00095     do {
00096 
00097       // Verify parameters.
00098 
00099         if( ! verifyElement( theRef )) {
00100             cout << errorStr << endl
00101                  << "    The specified object has not passed the general verification." << endl;
00102             break;
00103         }
00104 
00105       // Check if the currenbt collection does not have an element
00106       // with the same name.
00107 
00108         ooVString name = theRef->name( );
00109 
00110         if( useName( )) {
00111             if( _mapRef->isMember( name.head( ))) {
00112                 cout << errorStr << endl
00113                      << "    The collection already has an element with such name." << endl
00114                      << "        Passed element name: " << name.head( ) << endl;
00115                 break;
00116             }
00117         }
00118 
00119       // And the same test for the B-tree
00120 
00121         BTreeEntry newEntry( theRef->id( ), theRef );
00122 
00123         if( useId( )) {
00124             if( _treeRef->search( newEntry )) {
00125                 cout << errorStr << endl
00126                      << "    The collection already has an element with such identifier." << endl
00127                      << "        Passed element identifier: " << newEntry.key << endl;
00128                 break;
00129             }
00130         }
00131 
00132       // And finally - do the insertion into either or both the map and B-tree.
00133 
00134         if( useName( )) {
00135             if( BdbcSuccess != _mapRef->add( name.head( ), theRef )) {
00136                 cout << errorStr << endl
00137                      << "    Failed to insert new element into the collection's persistent map" << endl
00138                      << "        Passed element name:       " << name.head( ) << endl
00139                      << "                       identifier: " << newEntry.key << endl;
00140                 break;
00141             }
00142         }
00143         if( useId( )) {
00144             _treeRef->insert( newEntry );
00145         }
00146 
00147         ++_elements;
00148 
00149       // Done.
00150 
00151         result = CdbStatus::Success;
00152 
00153     } while( false );
00154 
00155     return result;
00156 }
00157 
00158 CdbStatus
00159 CdbBdbSCollectionP::find( const char*                           theName,
00160                           BdbRef( CdbBdbSCollectionElementP )&  theRef ) const
00161 {
00162   // Check for missuse of the method
00163 
00164     if( ! useName( )) {
00165         assert(0);
00166         return CdbStatus::Error;
00167     }
00168 
00169   // Proceed with finding
00170 
00171     const char* errorStr = "CdbBdbSCollectionP::find(name) -- ERROR";
00172     const char* fatalStr = "CdbBdbSCollectionP::find(name) -- FATAL ERROR";
00173 
00174     CdbStatus result = CdbStatus::Error;
00175     do {
00176 
00177       // Verify parameters.
00178 
00179         if( 0 == theName ) {
00180             cout << errorStr << endl
00181                  << "    Invalid name passed to the procedure." << endl;
00182             break;
00183         }
00184 
00185       // Look for an object with such name in the map.
00186 
00187         BdbRef(BdbPersObj) oRef;
00188 
00189         if( BdbcSuccess != _mapRef->lookup( theName, oRef )) {
00190             result = CdbStatus::NotFound;
00191             break;
00192         }
00193 
00194       // Verify found object type against what _MUST_ be in the collection.
00195 
00196         if( BdbIsNull(oRef)   ||
00197             ! oRef.isValid( )  ||
00198             ! oRef->ooIsKindOf( ooTypeN( CdbBdbSCollectionElementP ))) {
00199 
00200             cout << fatalStr << endl
00201                  << "    INCONSISTENT COLLECTION OR INAPPROPRIATE TYPE" << endl
00202                  << "    PASSED AS THE TEMPLATE PARAMETER." << endl;
00203 
00204             assert(0);
00205 
00206             break;
00207         }
00208         theRef = (const BdbRef( CdbBdbSCollectionElementP )&) oRef;
00209 
00210       // Done.
00211 
00212         result = CdbStatus::Success;
00213 
00214     } while( false );
00215 
00216     return result;
00217 }
00218 
00219 CdbStatus
00220 CdbBdbSCollectionP::find( d_UShort                             theId,
00221                           BdbRef( CdbBdbSCollectionElementP )& theRef ) const
00222 {
00223   // Check for missuse of the method
00224 
00225     if( ! useId( )) {
00226         assert(0);
00227         return CdbStatus::Error;
00228     }
00229 
00230   // Proceed with finding
00231 
00232     const char* fatalStr = "CdbBdbSCollectionP::find(id) -- FATAL ERROR";
00233 
00234     CdbStatus result = CdbStatus::Error;
00235     do {
00236 
00237       // Look for an object with such identifier in the B-tree.
00238         
00239         BTreeEntry foundEntry;
00240 
00241         if( ! _treeRef->search( BTreeEntry( theId ), foundEntry )) {
00242             result = CdbStatus::NotFound;
00243             break;
00244         }
00245         BdbRef( CdbBdbSCollectionElementP ) oRef = foundEntry.value;
00246 
00247       // Verify found object type against what _MUST_ be in the collection.
00248 
00249         if( BdbIsNull(oRef)   ||
00250             ! oRef.isValid( )  ||
00251             ! oRef->ooIsKindOf( ooTypeN( CdbBdbSCollectionElementP ))) {
00252 
00253             cout << fatalStr << endl
00254                  << "    INCONSISTENT COLLECTION OR INAPPROPRIATE TYPE" << endl
00255                  << "    PASSED AS THE TEMPLATE PARAMETER." << endl;
00256 
00257             assert(0);
00258 
00259             break;
00260         }
00261         theRef = oRef;
00262 
00263       // Done.
00264 
00265         result = CdbStatus::Success;
00266 
00267     } while( false );
00268 
00269     return result;
00270 }
00271 
00272 CdbStatus
00273 CdbBdbSCollectionP::remove( const char* theName )
00274 {
00275   // Check for missuse of the method
00276 
00277     if( ! useName( )) {
00278         assert(0);
00279         return CdbStatus::Error;
00280     }
00281 
00282   // Proceed with removal
00283 
00284     ooUpdate( );
00285 
00286     BdbRef( CdbBdbSCollectionElementP ) pRef;
00287 
00288     CdbStatus result = find( theName, pRef );
00289     if( CdbStatus::Success == result ) {
00290 
00291         if( useId( )) _treeRef->remove( BTreeEntry( pRef->id( )));
00292         _mapRef->remove( theName );
00293 
00294         BdbDelete( pRef );
00295 
00296         --_elements;
00297     }
00298 
00299     return result;
00300 }
00301 
00302 CdbStatus
00303 CdbBdbSCollectionP::remove( d_UShort theId )
00304 {
00305   // Check for missuse of the method
00306 
00307     if( ! useId( )) {
00308         assert(0);
00309         return CdbStatus::Error;
00310     }
00311 
00312   // Proceed with removal
00313 
00314     ooUpdate( );
00315 
00316     BdbRef( CdbBdbSCollectionElementP ) pRef;
00317 
00318     CdbStatus result = find( theId, pRef );
00319     if( CdbStatus::Success == result ) {
00320 
00321         _treeRef->remove( BTreeEntry( theId ));
00322         if( useName( )) _mapRef->remove( pRef->name( ));
00323 
00324         BdbDelete( pRef );
00325 
00326         --_elements;
00327     }
00328 
00329     return result;
00330 }
00331 
00332 CdbBdbSCollectionP::IteratorOfNames
00333 CdbBdbSCollectionP::iterator_names( ) const
00334 {
00335   // Check for missuse of the method
00336 
00337     if( ! useName( )) {
00338         assert(0);
00339         return IteratorOfNames( 0 );
00340     }
00341 
00342   // ATTENTION: This is not a memory leak - the created object
00343   //            will be destroyed by the iterator.
00344 
00345     return IteratorOfNames( new CdbBdbSCollectionNameItr( _mapRef ));
00346 }
00347 
00348 CdbBdbSCollectionP::IteratorOfIdentifiers
00349 CdbBdbSCollectionP::iterator_identifiers( ) const
00350 {
00351   // Check for missuse of the method
00352 
00353     if( ! useId( )) {
00354         assert(0);
00355         return IteratorOfIdentifiers( 0 );
00356     }
00357 
00358   // ATTENTION: This is not a memory leak - the created object
00359   //            will be destroyed by the iterator.
00360 
00361     return IteratorOfIdentifiers( new CdbBdbSCollectionIdItr( _treeRef->iterator( )));
00362 }
00363 
00364 
00365 void
00366 CdbBdbSCollectionP::dump( ostream& o ) const
00367 {
00368     if( useName( )) {
00369 
00370         o << "====================================" << endl
00371           << "== ELEMENTS SORTED BY THEIR NAMES ==" << endl
00372           << "====================================" << endl
00373           << endl;
00374 
00375         d_ULong num = 0;
00376 
00377         IteratorOfNames itr = iterator_names( );
00378         while( itr.next( )) {
00379 
00380             BdbRef( CdbBdbSCollectionElementP ) pRef;
00381             if( CdbStatus::Success != find( itr.value( ), pRef )) {
00382                 o << "%%% ERROR : ELEMENT WITH NAME: \"" << itr.value( ) << "\" NOT FOUND %%%" << endl;
00383             } else {
00384                 o << "\"" << pRef->name( ) << "\"" << endl;
00385                 ++num;
00386             }
00387             o << endl;
00388         }
00389 
00390         o << "== TOTAL OF " << num << "/" << elements( ) << " ELEMENTS WERE FOUND ==" << endl
00391           << endl;
00392     }
00393 
00394     if( useId( )) {
00395 
00396         o << "==========================================" << endl
00397           << "== ELEMENTS SORTED BY THEIR IDENTIFIERS ==" << endl
00398           << "==========================================" << endl
00399           << endl;
00400 
00401         d_ULong num = 0;
00402 
00403         IteratorOfIdentifiers itr = iterator_identifiers( );
00404         while( itr.next( )) {
00405 
00406             BdbRef( CdbBdbSCollectionElementP ) pRef;
00407             if( CdbStatus::Success != find( itr.value( ), pRef )) {
00408                 o << "%%% ERROR : ELEMENT WITH ID: " << itr.value( ) << " NOT FOUND %%%" << endl;
00409             } else {
00410                 o << pRef->id( ) << endl;
00411                 ++num;
00412             }
00413             o << endl;
00414         }
00415 
00416         o << "== TOTAL OF " << num << "/" << elements( ) << " ELEMENTS WERE FOUND ==" << endl;
00417     }
00418 }
00419 
00420 bool
00421 CdbBdbSCollectionP::verifyElement( const BdbRef( CdbBdbSCollectionElementP )& theRef ) const
00422 {
00423     const char* errorStr = "CdbBdbSCollectionP::verifyElement() -- ERROR";
00424 
00425     bool result = false;
00426     do {
00427 
00428         if( BdbIsNull( theRef )) {
00429             cout << errorStr << endl
00430                  << "    The 0-0-0-0 reference passed where the persistent object" << endl
00431                  << "    of type " << ooTypeN( CdbBdbSCollectionElementP ) << " was expected." << endl;
00432             break;
00433         }
00434         if( ! theRef.isValid( )) {
00435             cout << errorStr << endl
00436                  << "    Non-valid reference passed where the persistent object" << endl
00437                  << "    of type " << ooTypeN( CdbBdbSCollectionElementP ) << " was expected." << endl;
00438             break;
00439         }
00440         if( ! theRef->ooIsKindOf( ooTypeN( CdbBdbSCollectionElementP ))) {
00441             cout << errorStr << endl
00442                  << "    An object of an incompatible or inappropriate persistent type passed" << endl
00443                  << "    to the collection." << endl
00444                  << "        Passed object's type number: " << theRef->ooGetTypeN( ) << endl
00445                  << "        Expected        type number: " << ooTypeN( CdbBdbSCollectionElementP ) << endl;
00446             break;
00447         }
00448 
00449       // The last test is the optional one. It's only done when the collection
00450       // is configured to use names of elements.
00451 
00452         if( useName( )) {
00453             if( 0 == theRef->name( ).length( )) {
00454                 cout << errorStr << endl
00455                      << "    The passed object does not have a valid name." << endl;
00456                 break;
00457             }
00458         }
00459 
00460         result = true;
00461 
00462     } while( false );
00463 
00464     return result;
00465 }
00466 
00467 /////////////////
00468 // End Of File //
00469 /////////////////

Generated on Mon Dec 5 18:22:01 2005 for CDB by doxygen1.3-rc3