00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "BaBar/BaBar.hh"
00010
00011 #include "CdbBdbShared/CdbBdbSRevCollectionP.hh"
00012
00013 #include <assert.h>
00014 using std::cout;
00015 using std::endl;
00016 using std::ostream;
00017
00018 namespace {
00019
00020
00021
00022
00023
00024 class RevisionIdIterator : public CdbItr<BdbTime>::InterfaceType {
00025
00026 private:
00027
00028
00029
00030 RevisionIdIterator( );
00031
00032
00033
00034 RevisionIdIterator& operator=( const RevisionIdIterator& theItr );
00035
00036 protected:
00037
00038
00039
00040
00041
00042
00043
00044
00045 RevisionIdIterator( const RevisionIdIterator& theItr ) :
00046 _itr(theItr._itr)
00047 { }
00048
00049 public:
00050
00051
00052
00053 RevisionIdIterator( const CdbBdbSTimeLineP< BdbRef(CdbBdbSRevisionP) >::IteratorOfIntervals& theItr ) :
00054 _itr(theItr)
00055 { }
00056
00057
00058
00059 virtual ~RevisionIdIterator( )
00060 { }
00061
00062
00063
00064
00065
00066
00067
00068
00069 virtual CdbStatus reset( )
00070 {
00071 return _itr.reset( );
00072 }
00073
00074
00075
00076
00077
00078
00079
00080 virtual bool next( )
00081 {
00082 if( _itr.next( )) {
00083
00084 CdbBdbSTimeLineInterval< BdbRef(CdbBdbSRevisionP) > i = _itr.value( );
00085
00086 BdbRef(CdbBdbSRevisionP) rRef = i.value;
00087
00088
00089
00090
00091
00092
00093
00094
00095 if( BdbIsNull(rRef)) return next( );
00096
00097 _value = rRef->id( );
00098
00099 return true;
00100 }
00101 return false;
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 virtual ValueType value( )
00114 {
00115 if( isValid( )) {
00116 return _value;
00117 }
00118
00119
00120
00121 return BdbTime::minusInfinity;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130 virtual bool isValid( )
00131 {
00132 return _itr.isValid( );
00133 }
00134
00135
00136
00137
00138
00139 virtual InterfaceType* clone( ) const
00140 {
00141 return new RevisionIdIterator( *this );
00142 }
00143
00144 private:
00145
00146
00147
00148 CdbBdbSTimeLineP< BdbRef(CdbBdbSRevisionP) >::IteratorOfIntervals _itr;
00149
00150 BdbTime _value;
00151 };
00152
00153
00154
00155
00156
00157 class RevisionNameIterator : public CdbItr<const char*>::InterfaceType {
00158
00159 private:
00160
00161
00162
00163 RevisionNameIterator( );
00164
00165
00166
00167 RevisionNameIterator& operator=( const RevisionNameIterator& theItr );
00168
00169 protected:
00170
00171
00172
00173
00174
00175
00176
00177
00178 RevisionNameIterator( const RevisionNameIterator& theItr ) :
00179 _itr(theItr._itr),
00180 _value(theItr._value)
00181 { }
00182
00183 public:
00184
00185
00186
00187 RevisionNameIterator( const CdbBdbSTimeLineP< BdbRef(CdbBdbSRevisionP) >::IteratorOfIntervals& theItr ) :
00188 _itr(theItr),
00189 _value("")
00190 { }
00191
00192
00193
00194 virtual ~RevisionNameIterator( )
00195 { }
00196
00197
00198
00199
00200
00201
00202
00203
00204 virtual CdbStatus reset( )
00205 {
00206 return _itr.reset( );
00207 }
00208
00209
00210
00211
00212
00213
00214
00215 virtual bool next( )
00216 {
00217 if( _itr.next( )) {
00218
00219 CdbBdbSTimeLineInterval< BdbRef(CdbBdbSRevisionP) > i = _itr.value( );
00220
00221 BdbRef(CdbBdbSRevisionP) rRef = i.value;
00222
00223
00224
00225
00226
00227
00228
00229
00230 if( BdbIsNull(rRef)) return next( );
00231
00232 _value = rRef->name( );
00233
00234 return true;
00235 }
00236 return false;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 virtual ValueType value( )
00249 {
00250 if( isValid( )) {
00251 return _value.c_str( );
00252 }
00253
00254
00255
00256 return 0;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265 virtual bool isValid( )
00266 {
00267 return _itr.isValid( );
00268 }
00269
00270
00271
00272
00273
00274 virtual InterfaceType* clone( ) const
00275 {
00276 return new RevisionNameIterator( *this );
00277 }
00278
00279 private:
00280
00281
00282
00283 CdbBdbSTimeLineP< BdbRef(CdbBdbSRevisionP) >::IteratorOfIntervals _itr;
00284
00285 std::string _value;
00286 };
00287 };
00288
00289
00290
00291
00292
00293 CdbBdbSRevCollectionP::CdbBdbSRevCollectionP( )
00294 {
00295 _timeLineRef = new( ooThis( )) CdbBdbSTimeLineP< BdbRef(CdbBdbSRevisionP) >( );
00296 _mapRef = new( ooThis( )) BdbMap( );
00297 }
00298
00299 CdbBdbSRevCollectionP::~CdbBdbSRevCollectionP( )
00300 {
00301
00302
00303 CdbBdbSTimeLineP< BdbRef(CdbBdbSRevisionP) >::IteratorOfIntervals itr
00304 = _timeLineRef->iterator( );
00305
00306 while( itr.next( )) {
00307
00308 Interval i = itr.value( );
00309
00310 BdbRef(CdbBdbSRevisionP) revisionRef = i.value;
00311 if( ! BdbIsNull(revisionRef)) BdbDelete( revisionRef );
00312 }
00313
00314
00315
00316 BdbDelete( _timeLineRef );
00317 BdbDelete( _mapRef );
00318 }
00319
00320 CdbStatus
00321 CdbBdbSRevCollectionP::insert( const BdbRef(CdbBdbSRevisionP)& theRevisionRef )
00322 {
00323 const char* errorMsg = "CdbBdbSRevCollectionP::insert() -- ERROR";
00324
00325 ooUpdate( );
00326
00327 CdbStatus result = CdbStatus::Error;
00328 do {
00329
00330
00331
00332 if( BdbIsNull(theRevisionRef) || !theRevisionRef.isValid( )) {
00333 cout << errorMsg << endl
00334 << " Null or invalid persistent revision object " << theRevisionRef.sprint( ) << " passed to the procedure." << endl;
00335 break;
00336 }
00337 BdbTime id = theRevisionRef->id( );
00338 ooVString name = theRevisionRef->name( );
00339
00340 if(( BdbTime::minusInfinity == id ) || ( BdbTime::plusInfinity == id )) {
00341 cout << errorMsg << endl << " Passed persistent revision object has invalid identifier. " << endl;
00342 break;
00343 }
00344 if( 0 == name.length( )) {
00345 cout << errorMsg << endl << " Passed persistent revision object does not have a name. " << endl;
00346 break;
00347 }
00348
00349
00350
00351
00352
00353
00354
00355 if( CdbStatus::Success != insertIntoMap( theRevisionRef)) {
00356 break;
00357 }
00358 if( CdbStatus::Success != insertIntoTimeLine( theRevisionRef )) {
00359 removeFromMap( name.head( ));
00360 break;
00361 }
00362
00363
00364
00365 result = CdbStatus::Success;
00366
00367 } while( false );
00368
00369 return result;
00370 }
00371
00372 CdbStatus
00373 CdbBdbSRevCollectionP::find( const BdbTime& theId,
00374 BdbRef(CdbBdbSRevisionP)& theRevisionRef ) const
00375 {
00376 const char* errorMsg = "CdbBdbSRevCollectionP::find(id) -- ERROR";
00377
00378 CdbStatus result = CdbStatus::Error;
00379 do {
00380
00381
00382
00383 if(( BdbTime::minusInfinity == theId ) || ( BdbTime::plusInfinity == theId )) {
00384 cout << errorMsg << endl
00385 << " Passed revision identifier is not valid in this context." << endl
00386 << " ID: " << theId << endl;
00387 break;
00388 }
00389
00390
00391
00392
00393 Interval i;
00394 if(( ! _timeLineRef->findAtBegin( i, theId )) || BdbIsNull(i.value)) {
00395 result = CdbStatus::NotFound;
00396 break;
00397 }
00398 theRevisionRef = i.value;
00399
00400
00401
00402 result = CdbStatus::Success;
00403
00404 } while( false );
00405
00406 return result;
00407 }
00408
00409 CdbStatus
00410 CdbBdbSRevCollectionP::find( const char* theName,
00411 BdbRef(CdbBdbSRevisionP)& theRevisionRef ) const
00412 {
00413 const char* errorMsg = "CdbBdbSRevCollectionP::find(name) -- ERROR";
00414
00415 CdbStatus result = CdbStatus::Error;
00416 do {
00417
00418
00419
00420 if( 0 == theName ) {
00421 cout << errorMsg << endl
00422 << " Passed revision name can't be 0 in this context." << endl;
00423 break;
00424 }
00425
00426
00427
00428
00429
00430
00431 BdbRef(BdbPersObj) objectRef;
00432 if( BdbcSuccess != _mapRef->lookup( theName,
00433 objectRef )) {
00434 result = CdbStatus::NotFound;
00435 break;
00436 }
00437
00438
00439
00440 BdbRef(CdbBdbSRevisionP) revisionRef = (const BdbRef(CdbBdbSRevisionP)&) objectRef;
00441 if( !revisionRef.isValid( ) || BdbIsNull(revisionRef)) {
00442
00443 cout << errorMsg << endl
00444 << " Fatal internal error #2." << endl
00445 << " Map contain elements of unexpected persistent type." << endl;
00446
00447 assert( 0 );
00448
00449 break;
00450 }
00451 theRevisionRef = revisionRef;
00452
00453
00454
00455 result = CdbStatus::Success;
00456
00457 } while( false );
00458
00459 return result;
00460 }
00461
00462 CdbStatus
00463 CdbBdbSRevCollectionP::last( BdbTime& theId ) const
00464 {
00465 Interval i;
00466
00467 CdbStatus result = _timeLineRef->last( i );
00468 if( CdbStatus::Success == result ) theId = i.begin;
00469
00470 return result;
00471 }
00472
00473 CdbItr<BdbTime>
00474 CdbBdbSRevCollectionP::iterator_identifiers( ) const
00475 {
00476
00477
00478
00479 return CdbItr<BdbTime>( new RevisionIdIterator( _timeLineRef->iterator( )));
00480 }
00481
00482
00483 CdbItr<const char*>
00484 CdbBdbSRevCollectionP::iterator_names( ) const
00485 {
00486
00487
00488
00489 return CdbItr<const char*>( new RevisionNameIterator( _timeLineRef->iterator( )));
00490 }
00491
00492 void
00493 CdbBdbSRevCollectionP::dump( ostream& o ) const
00494 {
00495 do {
00496
00497
00498
00499 o << "=== REVISIONS COLLECTION ===" << endl
00500 << endl;
00501
00502 CdbBdbSTimeLineP< BdbRef(CdbBdbSRevisionP) >::IteratorOfIntervals itr
00503 = _timeLineRef->iterator( );
00504
00505 while( itr.next( )) {
00506
00507 Interval i = itr.value( );
00508
00509 BdbRef(CdbBdbSRevisionP) revisionRef = i.value;
00510 if( BdbIsNull(revisionRef)) {
00511
00512 o << " <IS EMPTY>" << endl
00513 << endl;
00514
00515 } else {
00516
00517 o << revisionRef.sprint( ) << endl
00518 << endl
00519 << " ID: " << revisionRef->id( ) << endl
00520 << " NAME: " << revisionRef->name( ).head( ) << endl
00521 << " VI COLLECTION: " << revisionRef->collection( ).sprint( ) << endl
00522 << " DURATION: " << "[ " << i.begin.getGmtSec( ) << "." << i.begin.getGmtNsec( ) << " , "
00523 << i.end.getGmtSec ( ) << "." << i.end.getGmtNsec ( ) << " )" << endl
00524 << endl;
00525 }
00526 }
00527
00528 o << "=== END OF COLLECTION ===" << endl;
00529
00530 } while( false );
00531 }
00532
00533 CdbStatus
00534 CdbBdbSRevCollectionP::insertIntoMap( const BdbRef(CdbBdbSRevisionP)& theRevisionRef )
00535 {
00536 const char* errorMsg = "CdbBdbSRevCollectionP::insertIntoMap() -- ERROR";
00537
00538 CdbStatus result = CdbStatus::Error;
00539 do {
00540
00541
00542
00543 ooVString name = theRevisionRef->name( );
00544
00545 if( _mapRef->isMember( name.head( ))) {
00546 cout << errorMsg << endl
00547 << " There is already a revision with such name." << endl
00548 << " Passed revision name: " << name.head( ) << endl;
00549 break;
00550 }
00551
00552
00553
00554 if( BdbcSuccess != _mapRef->add( name.head( ), theRevisionRef )) {
00555 cout << errorMsg << endl
00556 << " Failed to add new name to the map." << endl
00557 << " Passed revision name: " << name.head( ) << endl;
00558 break;
00559 }
00560
00561
00562
00563 result = CdbStatus::Success;
00564
00565 } while( false );
00566
00567 return result;
00568 }
00569
00570 void
00571 CdbBdbSRevCollectionP::removeFromMap( const char* theName )
00572 {
00573 _mapRef->remove( theName );
00574 }
00575
00576 CdbStatus
00577 CdbBdbSRevCollectionP::insertIntoTimeLine( const BdbRef(CdbBdbSRevisionP)& theRevisionRef )
00578 {
00579 const char* errorMsg = "CdbBdbSRevCollectionP::insertIntoTimeLine() -- ERROR";
00580
00581 CdbStatus result = CdbStatus::Error;
00582 do {
00583
00584
00585
00586
00587 BdbTime id = theRevisionRef->id( );
00588
00589 Interval lastInterval;
00590 if( CdbStatus::Success != _timeLineRef->last( lastInterval )) {
00591 cout << errorMsg << endl
00592 << " Failed to obtain the last interval from the TimeLine." << endl;
00593 break;
00594 }
00595 if( id <= lastInterval.begin ) {
00596 cout << errorMsg << endl
00597 << " Passed revision object has incorrect identifier time, which" << endl
00598 << " should never be less or equal than the one of the last known revision." << endl
00599 << " Passed revision ID: " << id << endl
00600 << " Last known revision ID: " << lastInterval.begin << endl;
00601 break;
00602 }
00603
00604
00605
00606
00607
00608
00609
00610 if( CdbStatus::Success != _timeLineRef->insert( id,
00611 BdbTime::plusInfinity,
00612 theRevisionRef )) {
00613 cout << errorMsg << endl
00614 << " Failed to insert new interval into the TimeLine." << endl;
00615 break;
00616 }
00617
00618
00619
00620 result = CdbStatus::Success;
00621
00622 } while( false );
00623
00624 return result;
00625 }
00626
00627
00628
00629