00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "BaBar/BaBar.hh"
00010
00011 #include "CdbBdbShared/CdbBdbSMetaDataP.hh"
00012 #include "CdbBdbShared/CdbBdbSRebuildAction.hh"
00013
00014 #include "CdbBdb/CdbBdbObjectClone.hh"
00015
00016 #include <iostream>
00017 #include <assert.h>
00018 #include <string.h>
00019 using std::cout;
00020 using std::endl;
00021
00022 namespace {
00023
00024
00025
00026
00027
00028 class RevisionIdIterator : public CdbItr<BdbTime>::InterfaceType {
00029
00030 private:
00031
00032
00033
00034 RevisionIdIterator( );
00035
00036
00037
00038 RevisionIdIterator& operator=( const RevisionIdIterator& theItr );
00039
00040 protected:
00041
00042
00043
00044
00045
00046
00047
00048
00049 RevisionIdIterator( const RevisionIdIterator& theItr ) :
00050 _revCollectionRef (theItr._revCollectionRef),
00051 _appendTopmostFlag (theItr._appendTopmostFlag),
00052 _isValid (theItr._isValid),
00053 _hasEverBeenAdvanced (theItr._hasEverBeenAdvanced),
00054 _value (theItr._value),
00055 _revItr (theItr._revItr),
00056 _thereIsTopmostToAppend(theItr._thereIsTopmostToAppend)
00057 { }
00058
00059 public:
00060
00061
00062
00063 RevisionIdIterator( const BdbRef(CdbBdbSRevCollectionP)& theRef,
00064 bool appendTopmostFlag ) :
00065 _revCollectionRef (theRef),
00066 _appendTopmostFlag (appendTopmostFlag),
00067 _isValid (false),
00068 _hasEverBeenAdvanced (false),
00069 _thereIsTopmostToAppend(appendTopmostFlag)
00070 {
00071 assert( !BdbIsNull(theRef));
00072 }
00073
00074
00075
00076 virtual ~RevisionIdIterator( )
00077 { }
00078
00079
00080
00081
00082
00083
00084
00085
00086 virtual CdbStatus reset( )
00087 {
00088 _isValid = false;
00089 _hasEverBeenAdvanced = false;
00090
00091 _thereIsTopmostToAppend = _appendTopmostFlag;
00092
00093 return CdbStatus::Success;
00094 }
00095
00096
00097
00098
00099
00100
00101
00102 virtual bool next( )
00103 {
00104 if( !_isValid ) {
00105
00106 if( !_hasEverBeenAdvanced ) {
00107 _hasEverBeenAdvanced = true;
00108
00109 _revItr = _revCollectionRef->iterator_identifiers( );
00110
00111 } else {
00112
00113
00114
00115
00116 return false;
00117 }
00118 }
00119 if( _isValid && _revItr.isValid( ) && _revItr.next( )) {
00120
00121
00122
00123 _value = _revItr.value( );
00124
00125 } else if( !_isValid && _revItr.next( )) {
00126
00127
00128
00129 _value = _revItr.value( );
00130 _isValid = true;
00131
00132 } else {
00133
00134
00135
00136
00137
00138 if( _thereIsTopmostToAppend ) {
00139 _thereIsTopmostToAppend = false;
00140
00141 _value = BdbTime::plusInfinity;
00142 _isValid = true;
00143
00144 } else {
00145
00146
00147
00148 _isValid = false;
00149 }
00150 }
00151 return _isValid;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 virtual ValueType value( )
00164 {
00165 if( _isValid ) {
00166 return _value;
00167 }
00168
00169
00170
00171 return BdbTime::minusInfinity;
00172 }
00173
00174
00175
00176
00177
00178
00179
00180 virtual bool isValid( )
00181 {
00182 return _isValid;
00183 }
00184
00185
00186
00187
00188
00189 virtual InterfaceType* clone( ) const
00190 {
00191 return new RevisionIdIterator( *this );
00192 }
00193
00194 private:
00195
00196 BdbRef(CdbBdbSRevCollectionP) _revCollectionRef;
00197 bool _appendTopmostFlag;
00198
00199 bool _isValid;
00200 bool _hasEverBeenAdvanced;
00201
00202 BdbTime _value;
00203
00204 CdbItr<BdbTime> _revItr;
00205
00206
00207
00208
00209
00210 bool _thereIsTopmostToAppend;
00211 };
00212
00213
00214
00215
00216
00217 class RevisionNameIterator : public CdbItr<const char*>::InterfaceType {
00218
00219 private:
00220
00221
00222
00223 RevisionNameIterator( );
00224
00225
00226
00227 RevisionNameIterator& operator=( const RevisionNameIterator& theItr );
00228
00229 protected:
00230
00231
00232
00233
00234
00235
00236
00237
00238 RevisionNameIterator( const RevisionNameIterator& theItr ) :
00239 _revCollectionRef (theItr._revCollectionRef),
00240 _appendTopmostFlag (theItr._appendTopmostFlag),
00241 _isValid (theItr._isValid),
00242 _hasEverBeenAdvanced (theItr._hasEverBeenAdvanced),
00243 _value (theItr._value),
00244 _revItr (theItr._revItr),
00245 _thereIsTopmostToAppend(theItr._thereIsTopmostToAppend)
00246 { }
00247
00248 public:
00249
00250
00251
00252 RevisionNameIterator( const BdbRef(CdbBdbSRevCollectionP)& theRef,
00253 bool appendTopmostFlag ) :
00254 _revCollectionRef (theRef),
00255 _appendTopmostFlag (appendTopmostFlag),
00256 _isValid (false),
00257 _hasEverBeenAdvanced (false),
00258 _value (""),
00259 _revItr (0),
00260 _thereIsTopmostToAppend(appendTopmostFlag)
00261 {
00262 assert( !BdbIsNull(theRef));
00263 }
00264
00265
00266
00267 virtual ~RevisionNameIterator( )
00268 { }
00269
00270
00271
00272
00273
00274
00275
00276
00277 virtual CdbStatus reset( )
00278 {
00279 _isValid = false;
00280 _hasEverBeenAdvanced = false;
00281
00282 _thereIsTopmostToAppend = _appendTopmostFlag;
00283
00284 return CdbStatus::Success;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293 virtual bool next( )
00294 {
00295 if( !_isValid ) {
00296
00297 if( !_hasEverBeenAdvanced ) {
00298 _hasEverBeenAdvanced = true;
00299
00300 _revItr = _revCollectionRef->iterator_names( );
00301
00302 } else {
00303
00304
00305
00306
00307 return false;
00308 }
00309 }
00310 if( _isValid && _revItr.isValid( ) && _revItr.next( )) {
00311
00312
00313
00314 _value = _revItr.value( );
00315
00316 } else if( !_isValid && _revItr.next( )) {
00317
00318
00319
00320 _value = _revItr.value( );
00321 _isValid = true;
00322
00323 } else {
00324
00325
00326
00327
00328
00329 if( _thereIsTopmostToAppend ) {
00330 _thereIsTopmostToAppend = false;
00331
00332 _value = "<topmost>";
00333 _isValid = true;
00334
00335 } else {
00336
00337
00338
00339 _isValid = false;
00340 }
00341 }
00342 return _isValid;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 virtual ValueType value( )
00355 {
00356 if( _isValid ) {
00357 return _value.c_str( );
00358 }
00359
00360
00361
00362 return 0;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371 virtual bool isValid( )
00372 {
00373 return _isValid;
00374 }
00375
00376
00377
00378
00379
00380 virtual InterfaceType* clone( ) const
00381 {
00382 return new RevisionNameIterator( *this );
00383 }
00384
00385 private:
00386
00387 BdbRef(CdbBdbSRevCollectionP) _revCollectionRef;
00388 bool _appendTopmostFlag;
00389
00390 bool _isValid;
00391 bool _hasEverBeenAdvanced;
00392
00393 std::string _value;
00394
00395 CdbItr<const char*> _revItr;
00396
00397
00398
00399
00400
00401 bool _thereIsTopmostToAppend;
00402 };
00403
00404
00405
00406
00407
00408 class CombinedIntervalIterator : public CdbItr<CdbBdbSCi>::InterfaceType {
00409
00410 private:
00411
00412
00413
00414 CombinedIntervalIterator( );
00415
00416
00417
00418 CombinedIntervalIterator& operator=( const CombinedIntervalIterator& theItr );
00419
00420 protected:
00421
00422
00423
00424
00425
00426
00427
00428
00429 CombinedIntervalIterator( const CombinedIntervalIterator& theItr ) :
00430 _viCollectionH (theItr._viCollectionH),
00431 _oiCollectionH (theItr._oiCollectionH),
00432 _beginTime (theItr._beginTime),
00433 _endTime (theItr._endTime),
00434 _isValid (theItr._isValid),
00435 _hasEverBeenAdvanced(theItr._hasEverBeenAdvanced),
00436 _value (theItr._value),
00437 _viItr (theItr._viItr)
00438 { }
00439
00440 public:
00441
00442
00443
00444 CombinedIntervalIterator( const BdbRef(CdbBdbSViCollectionP)& theViCollectionRef,
00445 const BdbRef(CdbBdbSOiCollectionP)& theOiCollectionRef,
00446 const BdbTime& theBeginTime,
00447 const BdbTime& theEndTime ) :
00448 _viCollectionH (theViCollectionRef),
00449 _oiCollectionH (theOiCollectionRef),
00450 _beginTime (theBeginTime),
00451 _endTime (theEndTime),
00452 _isValid (false),
00453 _hasEverBeenAdvanced(false)
00454 {
00455 assert( !BdbIsNull(theViCollectionRef));
00456 assert( !BdbIsNull(theOiCollectionRef));
00457 }
00458
00459
00460
00461 virtual ~CombinedIntervalIterator( )
00462 { }
00463
00464
00465
00466
00467
00468
00469
00470
00471 virtual CdbStatus reset( )
00472 {
00473 _isValid = false;
00474 _hasEverBeenAdvanced = false;
00475
00476 return CdbStatus::Success;
00477 }
00478
00479
00480
00481 bool tryNext( )
00482 {
00483 bool result = false;
00484 do {
00485
00486
00487
00488 if( !_viItr.next( )) break;
00489
00490 CdbBdbSVi vi = _viItr.value( );
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 if( ! ((( _beginTime <= vi.begin ) && ( vi.begin < _endTime )) ||
00517 (( vi.begin <= _beginTime ) && ( _beginTime < vi.end )))) break;
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 if( 0 == vi.value ) {
00528
00529
00530
00531
00532 _value = CdbBdbSCi( vi.begin,
00533 vi.end );
00534 } else {
00535
00536
00537
00538
00539 CdbBdbSOi oi;
00540 BdbTime beginOfDuration;
00541 BdbTime endOfDuration;
00542
00543 if( CdbStatus::Success != _oiCollectionH->find( vi.value,
00544 oi,
00545 beginOfDuration,
00546 endOfDuration )) {
00547
00548 assert( 0 );
00549
00550 break;
00551 }
00552 _value = CdbBdbSCi( vi.begin,
00553 vi.end,
00554 oi );
00555 }
00556
00557
00558
00559 result = true;
00560
00561 } while( false );
00562
00563 return result;
00564 }
00565
00566
00567
00568
00569
00570
00571
00572 virtual bool next( )
00573 {
00574 if( !_isValid ) {
00575
00576 if( !_hasEverBeenAdvanced ) {
00577 _hasEverBeenAdvanced = true;
00578
00579 _viItr = _viCollectionH->iterator( _beginTime );
00580
00581 } else {
00582
00583
00584
00585
00586 return false;
00587 }
00588 }
00589 if( !_isValid ) {
00590
00591
00592
00593 _isValid = tryNext( );
00594
00595 } else if( _isValid && _viItr.isValid( )) {
00596
00597
00598
00599 _isValid = tryNext( );
00600
00601 } else {
00602
00603
00604
00605 _isValid = false;
00606 }
00607 return _isValid;
00608 }
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619 virtual ValueType value( )
00620 {
00621 if( ! _isValid ) assert( 0 );
00622 return _value;
00623 }
00624
00625
00626
00627
00628
00629
00630
00631 virtual bool isValid( )
00632 {
00633 return _isValid;
00634 }
00635
00636
00637
00638
00639
00640 virtual InterfaceType* clone( ) const
00641 {
00642 return new CombinedIntervalIterator( *this );
00643 }
00644
00645 private:
00646
00647
00648
00649 BdbHandle(CdbBdbSViCollectionP) _viCollectionH;
00650 BdbHandle(CdbBdbSOiCollectionP) _oiCollectionH;
00651
00652 BdbTime _beginTime;
00653 BdbTime _endTime;
00654
00655
00656
00657 bool _isValid;
00658 bool _hasEverBeenAdvanced;
00659
00660 CdbBdbSCi _value;
00661
00662 CdbBdbSViCollectionP::IteratorOfIntervals _viItr;
00663 };
00664 };
00665
00666
00667
00668
00669
00670 CdbBdbSMetaDataP::CdbBdbSMetaDataP( const BdbTime& theMinValidityTime,
00671 const BdbTime& theMaxValidityTime,
00672 const BdbTime& theMinInsertionTime ) :
00673 _minValidityTime(theMinValidityTime),
00674 _maxValidityTime(theMaxValidityTime),
00675 _minInsertionTime(theMinInsertionTime),
00676 _maxInsertionTime(BdbTime::plusInfinity),
00677 _modified(theMinInsertionTime)
00678 {
00679 _originalCollectionRef = new( ooThis( )) CdbBdbSOiCollectionP( );
00680 _topmostRevisionRef = new( ooThis( )) CdbBdbSRevisionP( );
00681 _revCollectionRef = new( ooThis( )) CdbBdbSRevCollectionP( );
00682 }
00683
00684 CdbBdbSMetaDataP::~CdbBdbSMetaDataP( )
00685 {
00686 BdbDelete( _originalCollectionRef );
00687 BdbDelete( _topmostRevisionRef );
00688 BdbDelete( _revCollectionRef );
00689 }
00690
00691 BdbTime
00692 CdbBdbSMetaDataP::minValidity ( ) const
00693 {
00694 return _minValidityTime;
00695 }
00696
00697 BdbTime
00698 CdbBdbSMetaDataP::maxValidity ( ) const
00699 {
00700 return _maxValidityTime;
00701 }
00702
00703 BdbTime
00704 CdbBdbSMetaDataP::minInsertion( ) const
00705 {
00706 return _minInsertionTime;
00707 }
00708
00709 BdbTime
00710 CdbBdbSMetaDataP::maxInsertion( ) const
00711 {
00712 return _maxInsertionTime;
00713 }
00714
00715 BdbRef( CdbBdbSOiCollectionP )
00716 CdbBdbSMetaDataP::originaIntervalsCollection( ) const
00717 {
00718 return _originalCollectionRef;
00719 }
00720
00721 BdbTime
00722 CdbBdbSMetaDataP::modified( ) const
00723 {
00724 return _modified;
00725 }
00726
00727 CdbStatus
00728 CdbBdbSMetaDataP::close( const BdbTime& theMaxInsertionTime,
00729 const char* theNewRevisionName,
00730 const BdbTime& theNewRevisionCreationTime,
00731 const char* theNewRevisionDescription )
00732 {
00733 ooUpdate( );
00734
00735 const char* errorStr = "CdbBdbSMetaDataP::close() -- ERROR";
00736
00737 CdbStatus result = CdbStatus::Error;
00738 do {
00739
00740
00741
00742 if( CdbStatus::Success != verifyInsertionTime( theMaxInsertionTime )) {
00743 cout << errorStr << endl
00744 << " Specified insertion time is not correct." << endl
00745 << " See details above." << endl;
00746 break;
00747 }
00748 if( theMaxInsertionTime <= _modified ) {
00749 cout << errorStr << endl
00750 << " Specified insertion time is not correct." << endl
00751 << " Current operation requires this time to be strictly greater than" << endl
00752 << " the most recent modification time of the MetaData object." << endl
00753 << " PASSED MAX.INSERTION TIME: " << theMaxInsertionTime << endl
00754 << " CURRENT MODIFICATION TIME: " << _modified << endl;
00755 break;
00756 }
00757
00758
00759
00760
00761 BdbRef(CdbBdbSRevisionP) rRef;
00762 if( CdbStatus::Success != _revCollectionRef->find( _modified,
00763 rRef )) {
00764
00765
00766
00767 if(( 0 == theNewRevisionName ) ||
00768 ( BdbTime::minusInfinity == theNewRevisionCreationTime ) ||
00769 ( 0 == theNewRevisionDescription )) {
00770 cout << errorStr << endl
00771 << " Invalid revision parameters passed to the procedure when" << endl
00772 << " a final revision is about to be created. This revision has" << endl
00773 << " be created before closing the MetaData object." << endl;
00774 break;
00775 }
00776
00777
00778
00779 if( CdbStatus::Success != createRevision( _modified,
00780 theNewRevisionName,
00781 theNewRevisionCreationTime,
00782 theNewRevisionDescription )) {
00783 cout << errorStr << endl
00784 << " Failed to create new revision before closing the MetaData object." << endl;
00785 break;
00786 }
00787 }
00788
00789
00790
00791 BdbDelete(_topmostRevisionRef);
00792 _topmostRevisionRef = 0;
00793
00794
00795
00796 _maxInsertionTime = theMaxInsertionTime;
00797
00798
00799
00800 result = CdbStatus::Success;
00801
00802 } while( false );
00803
00804 return result;
00805 }
00806
00807 CdbStatus
00808 CdbBdbSMetaDataP::insert( const CdbBdbSOi& theInterval )
00809 {
00810 ooUpdate( );
00811
00812 const char* errorStr = "CdbBdbSMetaDataP::insert() -- ERROR";
00813 const char* fatalStr = "CdbBdbSMetaDataP::insert() -- FATAL INTERNAL ERROR!!!";
00814
00815 CdbStatus result = CdbStatus::Error;
00816 do {
00817
00818
00819
00820 if( CdbStatus::Success != verifyInsertionTime( theInterval.inserted )) {
00821 cout << errorStr << endl
00822 << " The insertion time of the passed interval is not correct." << endl
00823 << " See details above." << endl;
00824 break;
00825 }
00826 if( BdbIsNull( theInterval.object )) {
00827 cout << errorStr << endl
00828 << " The passed interval points to 0-0-0-0 condition object." << endl
00829 << " This interval can't be inserted." << endl;
00830 break;
00831 }
00832 if( theInterval.inserted < _modified ) {
00833 cout << errorStr << endl
00834 << " The insertion time of the passed interval is not correct." << endl
00835 << " Current operation requires this time to be greater or equal to" << endl
00836 << " the most recent modification time of the MetaData object." << endl
00837 << " PASSED INSERTION TIME: " << theInterval.inserted << endl
00838 << " CURRENT MODIFICATION TIME: " << _modified << endl;
00839 break;
00840 }
00841
00842
00843
00844
00845
00846 CdbBdbSOi oiInterval = theInterval;
00847
00848 if( oiInterval.begin < _minValidityTime ) oiInterval.begin = _minValidityTime;
00849 if( oiInterval.end > _maxValidityTime ) oiInterval.end = _maxValidityTime;
00850
00851 if( oiInterval.begin >= oiInterval.end ) {
00852 cout << errorStr << endl
00853 << " The passed interval does not have any cross-section" << endl
00854 << " with the validity window of the metadata object." << endl
00855 << " This interval can't be inserted." << endl;
00856 break;
00857 }
00858
00859
00860
00861 d_ULong oiIdx;
00862
00863
00864
00865 if( CdbStatus::Success != _originalCollectionRef->insert( oiInterval, oiIdx )) {
00866 cout << errorStr << endl
00867 << " Failed to register the interval in the 'original' intervals collection." << endl;
00868 break;
00869 }
00870
00871
00872
00873 if( CdbStatus::Success != _topmostRevisionRef->collection( )->insert( oiInterval.begin,
00874 oiInterval.end,
00875 oiIdx )) {
00876 cout << fatalStr << endl
00877 << " Failed to register the interval in the 'visible' intervals collection" << endl
00878 << " of the 'TOPMOST' revision. This puts the metadata object into" << endl
00879 << " an inconsistent state." << endl;
00880
00881 assert( 0 );
00882
00883 break;
00884 }
00885
00886
00887
00888 _modified = theInterval.inserted;
00889
00890
00891
00892 result = CdbStatus::Success;
00893
00894 } while( false );
00895
00896 return result;
00897 }
00898
00899 CdbStatus
00900 CdbBdbSMetaDataP:: rebuild( CdbBdbSRebuildAction* theRebuildAction,
00901 const BdbTime& theBeginTime,
00902 const BdbTime& theEndTime )
00903 {
00904 ooUpdate( );
00905
00906 const char* errorStr = "CdbBdbSMetaDataP::rebuild() -- ERROR";
00907 const char* fatalStr = "CdbBdbSMetaDataP::rebuild() -- FATAL INTERNAL ERROR!!!";
00908
00909 CdbStatus result = CdbStatus::Error;
00910 do {
00911
00912
00913
00914 if( theBeginTime >= theEndTime ) {
00915 cout << errorStr << endl
00916 << " Incorrect validity time range passed to the procedure." << endl;
00917 break;
00918 }
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936 {
00937 CdbItr<BdbTime> rItr;
00938 if( CdbStatus::Success != revisionIdIterator( rItr )) {
00939 cout << errorStr << endl
00940 << " Failed to get an iterator of revisions for the current metadata object." << endl;
00941 break;
00942 }
00943
00944 bool failed = false;
00945
00946 while( rItr.next( )) {
00947 if( BdbTime::plusInfinity != rItr.value( )) {
00948 if( rItr.value( ) >= theBeginTime ) {
00949 cout << errorStr << endl
00950 << " A non-topmost revision created at or after the specifid begin time" << endl
00951 << " passed to the procedure has been detected:" << endl
00952 << " REVISION ID : " << rItr.value( ).getGmtSec( ) << "." << rItr.value( ).getGmtNsec( ) << " " << rItr.value( ) << endl
00953 << " BEGIN TIME : " << theBeginTime.getGmtSec( ) << "." << theBeginTime.getGmtNsec( ) << " " << theBeginTime << endl
00954 << " The operation is not allowed for this metadata." << endl;
00955 failed = true;
00956 break;
00957 }
00958 }
00959 }
00960 if( failed ) break;
00961 }
00962
00963
00964
00965 if( BdbTime::plusInfinity != _maxInsertionTime ) {
00966 cout << errorStr << endl
00967 << " The current metadata object is in the 'closed' state." << endl
00968 << " The operation is not allowed for this metadata." << endl;
00969 break;
00970 }
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982 _modified = _minInsertionTime;
00983
00984
00985
00986
00987
00988 BdbHandle( CdbBdbSOiCollectionP ) inputOriginalCollectionH = _originalCollectionRef;
00989 _originalCollectionRef = new( ooThis( )) CdbBdbSOiCollectionP( );
00990
00991
00992
00993 BdbDelete(_topmostRevisionRef);
00994 _topmostRevisionRef = new( ooThis( )) CdbBdbSRevisionP( );
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004 BdbRef( CdbBdbSRevCollectionP ) savedRevCollectionRef = _revCollectionRef;
01005 _revCollectionRef = new( ooThis( )) CdbBdbSRevCollectionP( );
01006
01007
01008
01009
01010
01011
01012 bool failed = false;
01013
01014 d_ULong num = inputOriginalCollectionH->size( );
01015 for( d_ULong i = 1; i < num; ++i ) {
01016
01017
01018
01019 CdbBdbSOi oi;
01020
01021 BdbTime beginOfDuration;
01022 BdbTime endOfDuration;
01023
01024 if( CdbStatus::Success != inputOriginalCollectionH->find( i,
01025 oi,
01026 beginOfDuration,
01027 endOfDuration )) {
01028 cout << fatalStr << endl
01029 << " Failed to obtain an original interval with index " << i << " from the current collection." << endl
01030 << " The collection may be corrupted." << endl;
01031
01032 assert( 0 );
01033
01034 failed = true;
01035 break;
01036 }
01037
01038
01039
01040
01041
01042 CdbBdbSRebuildAction::ActionType action = CdbBdbSRebuildAction::ACTION_COPY;
01043
01044 if(( theBeginTime <= oi.inserted ) && ( oi.inserted < theEndTime )) {
01045
01046 action = theRebuildAction->userAction( oi );
01047 if( CdbBdbSRebuildAction::ACTION_ERROR == action ) {
01048
01049 cout << errorStr << endl
01050 << " User action has failed when processing an original interval." << endl;
01051
01052 failed = true;
01053 break;
01054 }
01055 }
01056
01057
01058
01059
01060
01061
01062
01063 if( CdbBdbSRebuildAction::ACTION_COPY == action ) {
01064 if( CdbStatus::Success != insert( oi )) {
01065 cout << errorStr << endl
01066 << " Failed to store an original interval in the rebuilt collection." << endl;
01067 failed = true;
01068 break;
01069 }
01070 }
01071 }
01072 if( failed ) break;
01073
01074
01075
01076
01077
01078
01079 BdbDelete(_revCollectionRef);
01080 _revCollectionRef = savedRevCollectionRef;
01081
01082 BdbTime recentlyModifiedTime = recentlyModified( );
01083 if( recentlyModifiedTime > _modified ) _modified = recentlyModifiedTime;
01084
01085
01086
01087
01088 BdbDelete( inputOriginalCollectionH );
01089
01090
01091
01092 result = CdbStatus::Success;
01093
01094 } while( false );
01095
01096 return result;
01097 }
01098
01099 CdbStatus
01100 CdbBdbSMetaDataP::repoint( CdbBdbObjectClone& theObjectCloningTool,
01101 CdbBdbCache<ooRef(ooObj)>& theTranslationDictionary )
01102 {
01103 const char* fatalStr = "CdbBdbSMetaDataP::repoint() -- FATAL INTERNAL ERROR!!!";
01104 const char* errorStr = "CdbBdbSMetaDataP::repoint() -- ERROR";
01105
01106 CdbStatus result = CdbStatus::Error;
01107 do {
01108
01109
01110
01111 bool failed = false;
01112
01113 d_ULong num = _originalCollectionRef->size( );
01114 for( d_ULong i = 1; i < num; ++i ) {
01115
01116
01117
01118 CdbBdbSOi oi;
01119
01120 BdbTime beginOfDuration;
01121 BdbTime endOfDuration;
01122
01123 if( CdbStatus::Success != _originalCollectionRef->find( i,
01124 oi,
01125 beginOfDuration,
01126 endOfDuration )) {
01127 cout << fatalStr << endl
01128 << " Failed to obtain an original interval with index " << i << " from the current collection." << endl
01129 << " The collection may be corrupted." << endl;
01130
01131 assert( 0 );
01132
01133 failed = true;
01134 break;
01135 }
01136
01137
01138
01139 if( BdbIsNull( oi.object )) continue;
01140
01141
01142
01143 ooHandle(ooObj) oldH = oi.object;
01144 ooHandle(ooObj) newH = 0;
01145
01146 if( !theObjectCloningTool.clone( oldH,
01147 newH )) {
01148
01149 cout << errorStr << endl
01150 << " Failed to clone an old object from the original interval with index " << i << " from the current collection." << endl
01151 << " The collection may be corrupted. Or there may be some other problem with the federation." << endl;
01152
01153 failed = true;
01154 break;
01155 }
01156
01157
01158
01159
01160 ooRef(ooObj) newObjectRef = newH;
01161 oi.object = (BdbRef(BdbObject)) newObjectRef;
01162
01163 if( CdbStatus::Success != _originalCollectionRef->replace( oi,
01164 i )) {
01165 cout << errorStr << endl
01166 << " Failed to replace the original interval with updated one at index " << i << " of the current collection." << endl;
01167
01168 failed = true;
01169 break;
01170 }
01171
01172
01173
01174
01175
01176
01177
01178
01179 ooRef(ooObj) oldObjectRef = oldH;
01180
01181 ooRef(ooObj) valueRef = theTranslationDictionary.findObject( oldObjectRef );
01182 if( 0 == valueRef ) {
01183 theTranslationDictionary.addObject( oldObjectRef,
01184 newObjectRef );
01185 } else {
01186 if( valueRef != newObjectRef ) {
01187
01188 cout << fatalStr << endl
01189 << " Dangerous inconsistency found in the data structures used by" << endl
01190 << " the repointing operation. The resulting metadata object may be useless." << endl
01191 << " This may be an indication of a serious bug in the caller's code." << endl;
01192
01193 assert( 0 );
01194
01195 failed = true;
01196 break;
01197 }
01198 }
01199 }
01200 if( failed ) break;
01201
01202
01203
01204 result = CdbStatus::Success;
01205
01206 } while( false );
01207
01208 return result;
01209 }
01210
01211
01212 CdbStatus
01213 CdbBdbSMetaDataP::findByRevision( const BdbTime& theRevisionId,
01214 const BdbTime& theValidityTime,
01215 CdbBdbSOi& theOriginalInterval,
01216 BdbTime& theBeginOfVisiblePeriod,
01217 BdbTime& theEndOfVisiblePeriod ) const
01218 {
01219 const char* errorStr = "CdbBdbSMetaDataP::findByRevision() -- ERROR";
01220 const char* fatalStr = "CdbBdbSMetaDataP::findByRevision() -- FATAL INTERNAL ERROR!!!";
01221
01222 CdbStatus result = CdbStatus::Error;
01223 do {
01224
01225
01226
01227 theBeginOfVisiblePeriod = _minValidityTime;
01228 theEndOfVisiblePeriod = _maxValidityTime;
01229
01230
01231
01232 if(( theValidityTime < _minValidityTime ) ||
01233 ( theValidityTime >= _maxValidityTime)) {
01234 cout << errorStr << endl
01235 << " The passed validity time is out of the validity window" << endl
01236 << " of the current metadata object." << endl;
01237 break;
01238 }
01239
01240
01241
01242
01243 BdbRef( CdbBdbSRevisionP ) revisionRef;
01244 if( BdbTime::plusInfinity == theRevisionId ) {
01245 if( BdbIsNull(_topmostRevisionRef)) {
01246 cout << errorStr << endl
01247 << " The topmost revision is not available in this Meta Data collection" << endl
01248 << " because the collection is closed." << endl;
01249 break;
01250 }
01251 revisionRef = _topmostRevisionRef;
01252 } else {
01253 if( CdbStatus::Success != _revCollectionRef->find( theRevisionId, revisionRef )) {
01254 cout << errorStr << endl
01255 << " Specified revision was not found in the collection." << endl
01256 << " PASSED REVISION ID: " << theRevisionId << endl;
01257 break;
01258 }
01259 }
01260 BdbRef( CdbBdbSViCollectionP ) collectionRef = revisionRef->collection( );
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276 CdbBdbSVi viInterval;
01277
01278 if( ! collectionRef->find( viInterval, theValidityTime )) {
01279
01280 assert( 0 );
01281
01282 break;
01283 }
01284
01285 theBeginOfVisiblePeriod = viInterval.begin;
01286 theEndOfVisiblePeriod = viInterval.end;
01287
01288 d_ULong oiIdx = viInterval.value;
01289 if( 0 == oiIdx ) {
01290 result = CdbStatus::NotFound;
01291 break;
01292 }
01293
01294
01295
01296
01297 BdbTime beginOfDurationPeriod( 0 );
01298 BdbTime endOfDurationPeriod ( 0 );
01299
01300 if( CdbStatus::Success != _originalCollectionRef->find( oiIdx,
01301 theOriginalInterval,
01302 beginOfDurationPeriod,
01303 endOfDurationPeriod )) {
01304 cout << fatalStr << endl
01305 << " The collection of 'visible' intervals does not match" << endl
01306 << " the collection of 'original' intervals." << endl;
01307
01308 assert( 0 );
01309
01310 break;
01311 }
01312
01313
01314
01315 result = CdbStatus::Success;
01316
01317 } while( false );
01318
01319 return result;
01320 }
01321
01322 CdbStatus
01323 CdbBdbSMetaDataP::findByRevision( const char* theRevisionName,
01324 const BdbTime& theValidityTime,
01325 CdbBdbSOi& theOriginalInterval,
01326 BdbTime& theBeginOfVisiblePeriod,
01327 BdbTime& theEndOfVisiblePeriod ) const
01328 {
01329 const char* errorStr = "CdbBdbSMetaDataP::findByRevision() -- ERROR";
01330
01331 CdbStatus result = CdbStatus::Error;
01332 do {
01333
01334
01335
01336 theBeginOfVisiblePeriod = _minValidityTime;
01337 theEndOfVisiblePeriod = _maxValidityTime;
01338
01339
01340
01341
01342 BdbTime revisionId( 0 );
01343
01344 if( 0 == theRevisionName ) {
01345 revisionId = BdbTime::plusInfinity;
01346 } else {
01347 BdbRef( CdbBdbSRevisionP ) revisionRef;
01348 if( CdbStatus::Success != _revCollectionRef->find( theRevisionName, revisionRef )) {
01349 cout << errorStr << endl
01350 << " Specified revision was not found in the collection." << endl
01351 << " PASSED REVISION NAME: " << theRevisionName << endl;
01352 break;
01353 }
01354 revisionId = revisionRef->id( );
01355 }
01356
01357
01358
01359 result = findByRevision( revisionId,
01360 theValidityTime,
01361 theOriginalInterval,
01362 theBeginOfVisiblePeriod,
01363 theEndOfVisiblePeriod );
01364
01365 } while( false );
01366
01367 return result;
01368 }
01369
01370 CdbStatus
01371 CdbBdbSMetaDataP::findByInsertion( const BdbTime& theInsertionTime,
01372 const BdbTime& theValidityTime,
01373 CdbBdbSOi& theOriginalInterval,
01374 BdbTime& theBeginOfDurationPeriod,
01375 BdbTime& theEndOfDurationPeriod ) const
01376 {
01377 const char* errorStr = "CdbBdbSMetaDataP::findByInsertion() -- ERROR";
01378
01379 CdbStatus result = CdbStatus::Error;
01380 do {
01381
01382
01383
01384 if(( theValidityTime < _minValidityTime ) ||
01385 ( theValidityTime >= _maxValidityTime)) {
01386 cout << errorStr << endl
01387 << " The passed validity time is out of the validity window" << endl
01388 << " of the current metadata object." << endl;
01389 break;
01390 }
01391 if(( theInsertionTime < _minInsertionTime ) ||
01392 ( theInsertionTime >= _maxInsertionTime)) {
01393 cout << errorStr << endl
01394 << " The passed insertion time is out of the insertion window" << endl
01395 << " of the current metadata object." << endl;
01396 break;
01397 }
01398
01399
01400
01401
01402
01403
01404
01405
01406 CdbStatus status = _originalCollectionRef->find( theInsertionTime,
01407 theOriginalInterval,
01408 theBeginOfDurationPeriod,
01409 theEndOfDurationPeriod );
01410 if( CdbStatus::Success != status ) {
01411 result = status;
01412 break;
01413 }
01414
01415
01416
01417
01418 if(( theValidityTime < theOriginalInterval.begin ) ||
01419 ( theValidityTime >= theOriginalInterval.end )) {
01420 cout << errorStr << endl
01421 << " This is inappropriate use of this finding method since" << endl
01422 << " the passed validity time does not fall into the 'validity' period" << endl
01423 << " of found 'original' interval." << endl;
01424 break;
01425 }
01426
01427
01428
01429 result = CdbStatus::Success;
01430
01431 } while( false );
01432
01433 return result;
01434 }
01435 CdbStatus
01436 CdbBdbSMetaDataP::findRevision( const BdbTime& theId,
01437 BdbRef(CdbBdbSRevisionP)& theRef ) const
01438 {
01439 CdbStatus result = CdbStatus::NotFound;
01440 do {
01441
01442
01443
01444
01445
01446
01447 if( theId < _minInsertionTime ) break;
01448 if(( BdbTime::plusInfinity != _maxInsertionTime ) && ( theId >= _maxInsertionTime )) break;
01449
01450
01451
01452 if( BdbTime::plusInfinity == theId ) {
01453
01454 if( !BdbIsNull(_topmostRevisionRef)) {
01455 theRef = _topmostRevisionRef;
01456 result = CdbStatus::Success;
01457 }
01458
01459 } else {
01460
01461
01462
01463 result = _revCollectionRef->find( theId,
01464 theRef );
01465 }
01466
01467 } while( false );
01468
01469 return result;
01470 }
01471
01472 CdbStatus
01473 CdbBdbSMetaDataP::findRevision( const char* theName,
01474 BdbRef(CdbBdbSRevisionP)& theRef ) const
01475 {
01476 const char* errorStr = "CdbBdbSMetaDataP::findRevision(name) -- ERROR";
01477
01478 CdbStatus result = CdbStatus::NotFound;
01479 do {
01480
01481
01482
01483 if( 0 == theName ) {
01484 cout << errorStr << endl
01485 << " Null pointer passed instead of a valid revision name." << endl;
01486 break;
01487 }
01488
01489
01490
01491 if( 0 == strcmp( "<topmost>", theName )) {
01492
01493 if( !BdbIsNull(_topmostRevisionRef)) {
01494 theRef = _topmostRevisionRef;
01495 result = CdbStatus::Success;
01496 }
01497
01498 } else {
01499
01500
01501
01502 result = _revCollectionRef->find( theName,
01503 theRef );
01504 }
01505
01506 } while( false );
01507
01508 return result;
01509 }
01510
01511 CdbStatus
01512 CdbBdbSMetaDataP::createRevision( const BdbTime& theId,
01513 const char* theName,
01514 const BdbTime& theCreationTime,
01515 const char* theDescription )
01516 {
01517 ooUpdate( );
01518
01519 const char* errorStr = "CdbBdbSMetaDataP::createRevision -- ERROR";
01520
01521 CdbStatus result = CdbStatus::Error;
01522 do {
01523
01524
01525
01526 if( CdbStatus::Success != verifyInsertionTime( theId )) {
01527 cout << errorStr << endl
01528 << " Specified revision identifier is not correct." << endl
01529 << " See details above." << endl;
01530 break;
01531 }
01532 if( 0 == strcmp( "<topmost>", theName )) {
01533 cout << errorStr << endl
01534 << " The special name '<topmost>' passed as a new revision name." << endl
01535 << " This name is reserved for the automatically created topmost revision" << endl
01536 << " and can't be used to create user-defined revisions." << endl;
01537 break;
01538 }
01539 if( theCreationTime < theId ) {
01540 cout << errorStr << endl
01541 << " Invalid revision creation time passsed to the procedure. This name should not" << endl
01542 << " be less than the revision identifiedr time." << endl
01543 << " PASSED REVISION ID: " << theId << endl
01544 << " PASSED REVISION CREATION TIME: " << theCreationTime << endl;
01545 break;
01546 }
01547 if( theId < _modified ) {
01548 cout << errorStr << endl
01549 << " The identifier time of the passed revision is not correct." << endl
01550 << " Current operation requires this time to be greater or equal to" << endl
01551 << " the most recent modification time of the MetaData object." << endl
01552 << " PASSED INSERTION TIME: " << theId << endl
01553 << " CURRENT MODIFICATION TIME: " << _modified << endl;
01554 break;
01555 }
01556 if( 0 == theDescription ) {
01557 cout << errorStr << endl
01558 << " Null pointer passed instead a valid revision description." << endl;
01559 break;
01560 }
01561
01562
01563
01564
01565 BdbRef(CdbBdbSRevisionP) revisionRef;
01566 revisionRef = new ( ooThis( )) CdbBdbSRevisionP( theId,
01567 theName,
01568 _topmostRevisionRef->collection( ),
01569 theCreationTime,
01570 theDescription );
01571
01572
01573
01574
01575
01576
01577 if( CdbStatus::Success != _revCollectionRef->insert( revisionRef )) {
01578 cout << errorStr << endl
01579 << " Failed to insert new revision into the collection." << endl;
01580 BdbDelete( revisionRef );
01581 break;
01582 }
01583
01584
01585
01586
01587 if( theId > _modified ) _modified = theId;
01588
01589
01590
01591 result = CdbStatus::Success;
01592
01593 } while( false );
01594
01595 return result;
01596 }
01597
01598 CdbStatus
01599 CdbBdbSMetaDataP::revisionIdIterator( CdbItr<BdbTime>& theItr ) const
01600 {
01601
01602
01603
01604 theItr = CdbItr<BdbTime>( new RevisionIdIterator( _revCollectionRef,
01605 !BdbIsNull(_topmostRevisionRef)));
01606 return CdbStatus::Success;
01607 }
01608
01609 CdbStatus
01610 CdbBdbSMetaDataP::revisionNameIterator( CdbItr<const char*>& theItr ) const
01611 {
01612
01613
01614
01615 theItr = CdbItr<const char*>( new RevisionNameIterator( _revCollectionRef,
01616 !BdbIsNull(_topmostRevisionRef)));
01617 return CdbStatus::Success;
01618 }
01619
01620 bool
01621 CdbBdbSMetaDataP::verifyObjectIteratorParameters( const BdbTime& theBeginTime,
01622 const BdbTime& theEndTime ) const
01623 {
01624 const char* errorStr = "CdbBdbSMetaDataP::verifyObjectIteratorParameters() -- ERROR";
01625
01626 bool result = false;
01627 do {
01628
01629
01630
01631 if( ! (( _minValidityTime <= theBeginTime ) && ( theBeginTime < _maxValidityTime ))) {
01632 cout << errorStr << endl
01633 << " Incorrect begin time passed to the method. It's out of the validity" << endl
01634 << " time window of the current meta-data object." << endl
01635 << " PASSED BEGIN TIME : " << theBeginTime << endl
01636 << " WINDOW BEGIN TIME : " << _minValidityTime << endl
01637 << " WINDOW END TIME : " << _maxValidityTime << endl;
01638 break;
01639 }
01640 if( ! (( _minValidityTime < theEndTime ) && ( theEndTime <= _maxValidityTime ))) {
01641 cout << errorStr << endl
01642 << " Incorrect end time passed to the method. It's out of the validity" << endl
01643 << " time window of the current meta-data object." << endl
01644 << " PASSED END TIME : " << theEndTime << endl
01645 << " WINDOW BEGIN TIME : " << _minValidityTime << endl
01646 << " WINDOW END TIME : " << _maxValidityTime << endl;
01647 break;
01648 }
01649 if( ! ( theBeginTime < theEndTime )) {
01650 cout << errorStr << endl
01651 << " Incorrect begin and end times passed to the method." << endl
01652 << " The begin time must be strictly less (older) than the end one. " << endl
01653 << " PASSED BEGIN TIME : " << theBeginTime << endl
01654 << " PASSED END TIME : " << theEndTime << endl;
01655 break;
01656 }
01657
01658
01659
01660 result = true;
01661
01662 } while( false );
01663
01664 return result;
01665 }
01666
01667 CdbStatus
01668 CdbBdbSMetaDataP::objectIterator( CdbItr<CdbBdbSCi>& theItr,
01669 const BdbTime& theRevisionId,
01670 const BdbTime& theBeginTime,
01671 const BdbTime& theEndTime ) const
01672 {
01673 const char* errorStr = "CdbBdbSMetaDataP::objectIterator(id) -- ERROR";
01674
01675 CdbStatus result = CdbStatus::Error;
01676 do {
01677
01678 if( ! verifyObjectIteratorParameters( theBeginTime,
01679 theEndTime )) break;
01680
01681
01682 BdbRef(CdbBdbSRevisionP) revisionRef;
01683 if( CdbStatus::Success != findRevision( theRevisionId,
01684 revisionRef )) {
01685 cout << errorStr << endl
01686 << " Failed to find a revision for specified identifier." << endl
01687 << " REVISION IDENTIFIER : " << theRevisionId << endl;
01688 }
01689
01690
01691
01692
01693 theItr = CdbItr<CdbBdbSCi>( new CombinedIntervalIterator( revisionRef->collection( ),
01694 _originalCollectionRef,
01695 theBeginTime,
01696 theEndTime ));
01697
01698
01699
01700 result = CdbStatus::Success;
01701
01702 } while( false );
01703
01704 return result;
01705 }
01706
01707 CdbStatus
01708 CdbBdbSMetaDataP::objectIterator( CdbItr<CdbBdbSCi>& theItr,
01709 const char* theName,
01710 const BdbTime& theBeginTime,
01711 const BdbTime& theEndTime ) const
01712 {
01713 const char* errorStr = "CdbBdbSMetaDataP::objectIterator(name) -- ERROR";
01714
01715 CdbStatus result = CdbStatus::Error;
01716 do {
01717
01718 if( ! verifyObjectIteratorParameters( theBeginTime,
01719 theEndTime )) break;
01720
01721
01722
01723 BdbRef(CdbBdbSRevisionP) revisionRef;
01724 if( CdbStatus::Success != findRevision( theName,
01725 revisionRef )) {
01726 cout << errorStr << endl
01727 << " Failed to find a revision for specified name." << endl
01728 << " REVISION NAME : " << theName << endl;
01729 break;
01730 }
01731
01732
01733
01734
01735 theItr = CdbItr<CdbBdbSCi>( new CombinedIntervalIterator( revisionRef->collection( ),
01736 _originalCollectionRef,
01737 theBeginTime,
01738 theEndTime ));
01739
01740
01741
01742 result = CdbStatus::Success;
01743
01744 } while( false );
01745
01746 return result;
01747 }
01748
01749 bool
01750 CdbBdbSMetaDataP::isClosed( ) const
01751 {
01752 return BdbTime::plusInfinity != _maxInsertionTime;
01753 }
01754
01755 BdbTime
01756 CdbBdbSMetaDataP::recentlyModified( ) const
01757 {
01758 BdbTime result = BdbTime::minusInfinity;
01759 {
01760
01761
01762 CdbBdbSOi lastOiInterval;
01763 if( CdbStatus::Success == _originalCollectionRef->last( lastOiInterval )) {
01764 if( lastOiInterval.inserted > result ) result = lastOiInterval.inserted;
01765 }
01766
01767
01768
01769
01770
01771
01772 BdbTime revId( 0 );
01773 if( CdbStatus::Success == _revCollectionRef->last( revId )) {
01774 if( revId > result ) result = revId;
01775 }
01776 }
01777 return result;
01778 }
01779
01780 CdbStatus
01781 CdbBdbSMetaDataP::verifyInsertionTime( const BdbTime& theTime ) const
01782 {
01783 const char* errorStr = "CdbBdbSMetaDataP::verifyInsertionTime -- ERROR";
01784
01785 CdbStatus result = CdbStatus::Error;
01786 do {
01787
01788
01789
01790 if( isClosed( )) {
01791 cout << errorStr << endl
01792 << " The metadata object is already closed for further modifications." << endl;
01793 break;
01794 }
01795
01796
01797
01798 if(( BdbTime::minusInfinity == theTime ) ||
01799 ( BdbTime::plusInfinity == theTime )) {
01800 cout << errorStr << endl
01801 << " Invalid value of the insertion time. It should not be" << endl
01802 << " equal neither '-Infinity' nor the '+Infinity'." << endl;
01803 break;
01804 }
01805
01806
01807
01808
01809 BdbTime recentModificationTime = recentlyModified( );
01810 if( theTime < recentModificationTime ) {
01811 cout << errorStr << endl
01812 << " The passed time must be greater or equal than the most recent" << endl
01813 << " modification time of the metadata window." << endl
01814 << " MODIFICATION TIME: " << recentModificationTime << endl
01815 << " PASSED INSERTION TIME: " << theTime << endl;
01816 break;
01817 }
01818
01819
01820
01821 result = CdbStatus::Success;
01822
01823 } while( false );
01824
01825 return result;
01826 }
01827
01828
01829
01830