00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "BaBar/BaBar.hh"
00010
00011 #include "CdbBdbShared/CdbBdbSPartitionsLayoutP.hh"
00012
00013 #include "CdbBase/CdbEnvironment.hh"
00014
00015 #include <iostream>
00016 #include <assert.h>
00017 #include <iomanip>
00018
00019 #include <vector>
00020 #include <list>
00021 using std::cout;
00022 using std::endl;
00023 using std::ostream;
00024 using std::setfill;
00025 using std::setw;
00026
00027 namespace {
00028
00029
00030
00031
00032
00033 class CdbBdbSPartitionIntervalItr : public CdbItr< CdbBdbSPartitionInterval >::InterfaceType {
00034
00035 private:
00036
00037 typedef CdbBdbSPartitionCell Cell;
00038 typedef CdbBdbSPartitionInterval Interval;
00039
00040 typedef std::vector<Cell> Cells;
00041 typedef std::list<Interval> Intervals;
00042
00043 private:
00044
00045 CdbBdbSPartitionIntervalItr( );
00046
00047 CdbBdbSPartitionIntervalItr& operator=( const CdbBdbSPartitionIntervalItr& theItr );
00048
00049 protected:
00050
00051 CdbBdbSPartitionIntervalItr( const CdbBdbSPartitionIntervalItr& theItr ) :
00052 _cells (theItr._cells),
00053 _begin (theItr._begin),
00054 _end (theItr._end),
00055 _isValid (theItr._isValid),
00056 _hasEverBeenAdvanced(theItr._hasEverBeenAdvanced),
00057 _valueIsBuilt (theItr._valueIsBuilt),
00058 _values (theItr._values),
00059 _currentValueItr (theItr._currentValueItr),
00060 _currentValue (theItr._currentValue)
00061 { }
00062
00063 public:
00064
00065 CdbBdbSPartitionIntervalItr( const Cells& theCells,
00066 const BdbTime& theBeginValidityTime,
00067 const BdbTime& theEndValidityTime ) :
00068 _cells (theCells),
00069 _begin (theBeginValidityTime),
00070 _end (theEndValidityTime),
00071 _isValid (false),
00072 _hasEverBeenAdvanced(false),
00073 _valueIsBuilt (false)
00074 {
00075 assert( theBeginValidityTime < theEndValidityTime );
00076 }
00077
00078 virtual ~CdbBdbSPartitionIntervalItr( )
00079 { }
00080
00081 virtual CdbStatus reset( )
00082 {
00083 _isValid = false;
00084 _hasEverBeenAdvanced = false;
00085
00086 return CdbStatus::Success;
00087 }
00088
00089 void buildNextNode( Cells::iterator theInCurrent,
00090 Intervals::iterator theOutCenter,
00091 const BdbTime& theBeginTime,
00092 const BdbTime& theEndTime )
00093 {
00094 const char* debugStr = "CdbBdbSCondition::CdbBdbSPartitionIntervalItr::buildNextNode()";
00095
00096 for( Cells::iterator i = theInCurrent; i != _cells.end( ); ++i ) {
00097
00098
00099 if( CdbEnvironment::getDebugMode( ) != 0 )
00100 cout << debugStr << endl
00101 << "{" << endl
00102 << " (*i) = " << (*i) << endl
00103 << " (*theOutCenter) = " << (*theOutCenter) << endl
00104 << "}" << endl;
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 Cell c = (*i);
00131
00132
00133
00134 if( c.cell.endValidity <= theBeginTime ) continue;
00135 if( c.cell.beginValidity >= theEndTime ) continue;
00136
00137
00138
00139 BdbTime begin = c.cell.beginValidity;
00140 if( begin < theBeginTime )
00141 begin = theBeginTime;
00142
00143 BdbTime end = c.cell.endValidity;
00144 if( end > theEndTime )
00145 end = theEndTime;
00146
00147
00148 if( CdbEnvironment::getDebugMode( ) != 0 )
00149 cout << debugStr << endl
00150 << "{" << endl
00151 << " begin = " << setw( 10 ) << setfill( '0' ) << begin.getGmtSec( ) << endl
00152 << " end = " << setw( 10 ) << setfill( '0' ) << end.getGmtSec( ) << endl
00153 << " theBeginTime = " << setw( 10 ) << setfill( '0' ) << theBeginTime.getGmtSec( ) << endl
00154 << " theEndTime = " << setw( 10 ) << setfill( '0' ) << theEndTime.getGmtSec( ) << endl
00155 << "}" << endl;
00156
00157
00158 if(( begin == theBeginTime ) &&
00159 ( end < theEndTime )) {
00160
00161
00162 if( CdbEnvironment::getDebugMode( ) != 0 )
00163 cout << debugStr << endl
00164 << "{" << endl
00165 << " -1-" << endl
00166 << "}" << endl;
00167
00168
00169
00170
00171 Interval left( c.id, begin, end );
00172 Interval right( end, theEndTime );
00173
00174 _values.insert( theOutCenter, left );
00175
00176 Intervals::iterator outRight = theOutCenter;
00177 if( _values.end( ) == theOutCenter ) {
00178 outRight = _values.insert( theOutCenter, right );
00179 } else {
00180 (*theOutCenter) = right;
00181 }
00182 Cells::iterator nextCell = i;
00183 ++nextCell;
00184 buildNextNode( nextCell, outRight, end, theEndTime );
00185
00186 return;
00187
00188 } else if(( begin == theBeginTime ) &&
00189 ( end == theEndTime )) {
00190
00191
00192 if( CdbEnvironment::getDebugMode( ) != 0 )
00193 cout << debugStr << endl
00194 << "{" << endl
00195 << " -2-" << endl
00196 << "}" << endl;
00197
00198
00199
00200
00201 Interval center( c.id, begin, end );
00202
00203 if( _values.end( ) == theOutCenter )
00204 _values.insert( theOutCenter, center );
00205 else
00206 (*theOutCenter) = center;
00207
00208 return;
00209
00210 } else if(( begin > theBeginTime ) &&
00211 ( end < theEndTime )) {
00212
00213
00214 if( CdbEnvironment::getDebugMode( ) != 0 )
00215 cout << debugStr << endl
00216 << "{" << endl
00217 << " -3-" << endl
00218 << "}" << endl;
00219
00220
00221
00222
00223 Interval left ( theBeginTime, begin );
00224 Interval center( c.id, begin, end );
00225 Interval right ( end, theEndTime );
00226
00227 Intervals::iterator outLeft = _values.insert( theOutCenter, left );
00228 _values.insert( theOutCenter, center );
00229 Intervals::iterator outRight = theOutCenter;
00230 if( _values.end( ) == theOutCenter ) {
00231 outRight = _values.insert( theOutCenter, right );
00232 } else {
00233 (*theOutCenter) = right;
00234 }
00235 Cells::iterator nextCell = i;
00236 ++nextCell;
00237 buildNextNode( nextCell, outLeft, theBeginTime, begin );
00238 buildNextNode( nextCell, outRight, end, theEndTime );
00239
00240 return;
00241
00242 } else if(( begin > theBeginTime ) &&
00243 ( end >= theEndTime )) {
00244
00245
00246 if( CdbEnvironment::getDebugMode( ) != 0 )
00247 cout << debugStr << endl
00248 << "{" << endl
00249 << " -4-" << endl
00250 << "}" << endl;
00251
00252
00253
00254
00255 Interval left( theBeginTime, begin );
00256 Interval right( c.id, begin, end );
00257
00258 Intervals::iterator outLeft = _values.insert( theOutCenter, left );
00259 if( _values.end( ) == theOutCenter ) {
00260 _values.insert( theOutCenter, right );
00261 } else {
00262 (*theOutCenter) = right;
00263 }
00264 Cells::iterator nextCell = i;
00265 ++nextCell;
00266 buildNextNode( nextCell, outLeft, theBeginTime, begin );
00267
00268 return;
00269
00270 } else {
00271 assert( 0 );
00272 }
00273 }
00274
00275
00276
00277
00278 if( _values.end( ) == theOutCenter ) {
00279
00280
00281 if( CdbEnvironment::getDebugMode( ) != 0 )
00282 cout << debugStr << endl
00283 << "{" << endl
00284 << " -default-" << endl
00285 << "}" << endl;
00286
00287
00288 _values.push_back( Interval( theBeginTime,
00289 theEndTime ));
00290 }
00291 }
00292
00293 void buildVectorOfValues( )
00294 {
00295 if( !_valueIsBuilt ) {
00296 _valueIsBuilt = true;
00297
00298 buildNextNode( _cells.begin( ),
00299 _values.end( ),
00300 _begin,
00301 _end );
00302 }
00303 _currentValueItr = _values.begin( );
00304 }
00305
00306 bool tryNext( )
00307 {
00308 bool result = _currentValueItr != _values.end( );
00309 if( result ) {
00310 _currentValue = *(_currentValueItr++);
00311 }
00312 return result;
00313 }
00314
00315 virtual bool next( )
00316 {
00317 if( _hasEverBeenAdvanced ) {
00318
00319 if( _isValid ) {
00320 _isValid = tryNext( );
00321 } else {
00322
00323
00324 ;
00325 }
00326
00327 } else {
00328
00329 buildVectorOfValues( );
00330
00331 _hasEverBeenAdvanced = true;
00332 _isValid = tryNext( );
00333 }
00334 return _isValid;
00335 }
00336
00337 virtual ValueType value( )
00338 {
00339 if( !_isValid ) {
00340 assert( 0 );
00341 }
00342 return _currentValue;
00343 }
00344
00345 virtual bool isValid( )
00346 {
00347 return _isValid;
00348 }
00349
00350 virtual InterfaceType* clone( ) const
00351 {
00352 return new CdbBdbSPartitionIntervalItr( *this );
00353 }
00354
00355 private:
00356
00357 Cells _cells;
00358
00359 BdbTime _begin;
00360 BdbTime _end;
00361
00362 bool _isValid;
00363 bool _hasEverBeenAdvanced;
00364
00365
00366
00367
00368 bool _valueIsBuilt;
00369
00370 Intervals _values;
00371 Intervals::iterator _currentValueItr;
00372 Interval _currentValue;
00373 };
00374
00375 };
00376
00377
00378
00379
00380
00381 CdbBdbSPartitionCell::CdbBdbSPartitionCell( ) :
00382 cell(CdbBdbSCell( )),
00383 id(0),
00384 partition(0)
00385 { }
00386
00387 CdbBdbSPartitionCell::CdbBdbSPartitionCell( const CdbBdbSCell& theCell,
00388 d_UShort theId,
00389 const BdbRef( CdbBdbSPartitionBaseP )& theRef ) :
00390 cell(theCell),
00391 id(theId),
00392 partition(theRef)
00393 { }
00394
00395 CdbBdbSPartitionCell::CdbBdbSPartitionCell( const CdbBdbSPartitionCell& theOther ) :
00396 cell(theOther.cell),
00397 id(theOther.id),
00398 partition(theOther.partition)
00399 { }
00400
00401 CdbBdbSPartitionCell::~CdbBdbSPartitionCell( )
00402 { }
00403
00404 CdbBdbSPartitionCell&
00405 CdbBdbSPartitionCell::operator=( const CdbBdbSPartitionCell& theOther )
00406 {
00407 const_cast< CdbBdbSCell& > ( cell ) = theOther.cell;
00408 const_cast< d_UShort& > ( id ) = theOther.id;
00409 const_cast< BdbRef( CdbBdbSPartitionBaseP )& >( partition ) = theOther.partition;
00410 return *this;
00411 }
00412
00413 void
00414 CdbBdbSPartitionCell::dump( ostream& o ) const
00415 {
00416 o << cell << endl
00417 << "ID : " << id << endl
00418 << "PARTITION : " << partition.sprint( ) << endl;
00419 }
00420
00421
00422
00423
00424
00425 CdbBdbSPartitionInterval::CdbBdbSPartitionInterval( const BdbTime& theBeginTime,
00426 const BdbTime& theEndTime ) :
00427 isEmpty(true),
00428 begin (theBeginTime),
00429 end (theEndTime)
00430 { }
00431
00432 CdbBdbSPartitionInterval::CdbBdbSPartitionInterval( d_UShort theId,
00433 const BdbTime& theBeginTime,
00434 const BdbTime& theEndTime ) :
00435 isEmpty(false),
00436 id (theId),
00437 begin (theBeginTime),
00438 end (theEndTime)
00439 { }
00440
00441 CdbBdbSPartitionInterval::CdbBdbSPartitionInterval( const CdbBdbSPartitionInterval& theOther ) :
00442 isEmpty(theOther.isEmpty),
00443 id (theOther.id),
00444 begin (theOther.begin),
00445 end (theOther.end)
00446 { }
00447
00448 CdbBdbSPartitionInterval::~CdbBdbSPartitionInterval( )
00449 { }
00450
00451 CdbBdbSPartitionInterval&
00452 CdbBdbSPartitionInterval::operator=( const CdbBdbSPartitionInterval& theOther )
00453 {
00454 if( this != &theOther ) {
00455 isEmpty = theOther.isEmpty;
00456 id = theOther.id;
00457 begin = theOther.begin;
00458 end = theOther.end;
00459 }
00460 return *this;
00461 }
00462
00463 void
00464 CdbBdbSPartitionInterval::dump( ostream& o ) const
00465 {
00466 o << "IS_EMPTY=" << ( isEmpty ? "Y" : "N" )
00467 << " "
00468 << "BEGIN="
00469 << setw( 10 ) << setfill( '0' ) << begin.getGmtSec( )
00470 << "."
00471 << setw( 10 ) << setfill( '0' ) << begin.getGmtNsec( )
00472 << " "
00473 << "END="
00474 << setw( 10 ) << setfill( '0' ) << end.getGmtSec( )
00475 << "."
00476 << setw( 10 ) << setfill( '0' ) << end.getGmtNsec( );
00477
00478 if( !isEmpty ) {
00479 cout << " "
00480 << "ID=" << id;
00481 }
00482 }
00483
00484
00485
00486
00487
00488 CdbBdbSPartitionsLayoutP::CdbBdbSPartitionsLayoutP( ) :
00489 _collectionP(0),
00490 _trivialIndexP(0),
00491 _complexIndexP(0)
00492 {
00493
00494
00495
00496 bool useIdFlag = true;
00497 bool useNameFlag = false;
00498
00499 _collectionP = new( ooThis( )) CdbBdbSCollectionP( useIdFlag,
00500 useNameFlag );
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 _trivialIndexP = new( ooThis( )) CdbBdbSPagedVarrayP< CdbBdbSPartitionCell >( );
00513 }
00514
00515 CdbBdbSPartitionsLayoutP::~CdbBdbSPartitionsLayoutP( )
00516 {
00517
00518
00519
00520 d_ULong num = _trivialIndexP->size( );
00521 for( d_ULong i = 0; i < num; ++i ) {
00522
00523 CdbBdbSPartitionCell pCell = _trivialIndexP->elementAt( i );
00524 BdbDelete(pCell.partition);
00525 }
00526 BdbDelete(_collectionP);
00527
00528
00529
00530 BdbDelete(_trivialIndexP);
00531
00532
00533
00534
00535
00536 if( ! BdbIsNull(_complexIndexP)) {
00537 cout << "CdbBdbSPartitionsLayoutP::~CdbBdbSPartitionsLayoutP( ) - WARNING!" << endl
00538 << " The destructor has detected non-zero optional COMPLEX index. This index" << endl
00539 << " can't be deleted by the current destructor. Use more recent implementation" << endl
00540 << " for this kind of operation." << endl
00541 << " INDEX OID: " << _complexIndexP.sprint( ) << endl;
00542 }
00543 }
00544
00545 d_ULong
00546 CdbBdbSPartitionsLayoutP::numPartitions( ) const
00547 {
00548 return _collectionP->elements( );
00549 }
00550
00551 CdbStatus
00552 CdbBdbSPartitionsLayoutP::insert( const BdbRef( CdbBdbSPartitionBaseP )& theRef )
00553 {
00554 const char* errorStr = "CdbBdbSPartitionsLayoutP::insert() - ERROR.";
00555
00556 ooUpdate( );
00557
00558 CdbStatus result = CdbStatus::Error;
00559 do {
00560
00561
00562
00563 if( BdbIsNull(theRef)) {
00564 cout << errorStr << endl
00565 << " 0-0-0-0 persistent reference passed where a pointer onto" << endl
00566 << " a partition object was expected." << endl;
00567 break;
00568 }
00569
00570
00571
00572 d_ULong id = theRef->id( );
00573
00574 BdbRef( CdbBdbSPartitionBaseP ) ref;
00575
00576 if( CdbStatus::Success == _collectionP->find( id,
00577 ref )) {
00578 cout << errorStr << endl
00579 << " The Layout already has a registered partition with the same identifier." << endl
00580 << " ID: " << id << endl
00581 << " PASSED PARTITION OID: " << theRef.sprint( ) << endl
00582 << " REGISTERED PARTITION OID: " << ref.sprint( ) << endl;
00583 break;
00584 }
00585
00586
00587
00588
00589 CdbBdbSCell cell = theRef->cell( );
00590
00591 bool overlap = false;
00592 {
00593 d_ULong num = _trivialIndexP->size( );
00594 for( d_ULong i = 0; i < num; ++i ) {
00595
00596 CdbBdbSPartitionCell pCell = _trivialIndexP->elementAt( i );
00597
00598 if( pCell.cell.overlap( cell )) {
00599 overlap = true;
00600 break;
00601 }
00602 }
00603 }
00604 if( overlap ) {
00605 cout << errorStr << endl
00606 << " One of the registered with the Layout partitions overlaps with" << endl
00607 << " with the one passed at the 2-dimension space of the VALIDITY" << endl
00608 << " and INSERTION timelines." << endl;
00609 break;
00610 }
00611
00612
00613
00614
00615
00616
00617
00618 if( CdbStatus::Success != _collectionP->insert( theRef )) {
00619 break;
00620 }
00621 d_ULong num = _trivialIndexP->size( );
00622 if( BdbcSuccess != _trivialIndexP->resize( num + 1 )) {
00623
00624 cout << errorStr << endl
00625 << " Failed to resize the trivial index to make a room for a new partition." << endl
00626 << " CURRENT SIZE: " << num << endl;
00627
00628 _collectionP->remove( id );
00629
00630 break;
00631 }
00632 _trivialIndexP->setElementAt( num,
00633 CdbBdbSPartitionCell( cell,
00634 id,
00635 theRef ));
00636
00637
00638
00639 result = CdbStatus::Success;
00640
00641 } while( false );
00642
00643 return result;
00644 }
00645
00646 CdbStatus
00647 CdbBdbSPartitionsLayoutP::update( const BdbRef( CdbBdbSPartitionBaseP )& theNewRef )
00648 {
00649 const char* errorStr = "CdbBdbSPartitionsLayoutP::update() - ERROR.";
00650
00651 ooUpdate( );
00652
00653 CdbStatus result = CdbStatus::NotFound;
00654 do {
00655
00656
00657
00658 if( BdbIsNull(theNewRef)) {
00659 cout << errorStr << endl
00660 << " 0-0-0-0 persistent reference passed where a pointer onto" << endl
00661 << " a partition object was expected." << endl;
00662 break;
00663 }
00664
00665
00666
00667
00668 bool updateIndexOnly = false;
00669 d_ULong oldCellIdx = 0;
00670 {
00671 const d_UShort pId = theNewRef->id( );
00672
00673 CdbBdbSPartitionCell pCell;
00674
00675 bool found = false;
00676
00677 d_ULong num = _trivialIndexP->size( );
00678 for( d_ULong i = 0; i < num; ++i ) {
00679
00680 pCell = _trivialIndexP->elementAt( i );
00681 if( pCell.id == pId ) {
00682
00683 oldCellIdx = i;
00684
00685 found = true;
00686 break;
00687 }
00688 }
00689 if( !found) break;
00690
00691
00692
00693
00694
00695 CdbBdbSCell newCell = theNewRef->cell( );
00696
00697 if(( newCell.beginValidity != pCell.cell.beginValidity ) ||
00698 ( newCell.endValidity != pCell.cell.endValidity ) ||
00699 ( newCell.beginInsertion != pCell.cell.beginInsertion )) {
00700
00701 cout << errorStr << endl
00702 << " The validity/insertion cell occupied by the new partition passed" << endl
00703 << " to the procedure does not match the old one." << endl
00704 << " NEW ->" << endl
00705 << newCell << endl
00706 << " OLD ->" << endl
00707 << pCell.cell << endl;
00708
00709 result = CdbStatus::Error;
00710
00711 break;
00712 }
00713
00714
00715
00716
00717 if( theNewRef == pCell.partition ) {
00718 updateIndexOnly = true;
00719 }
00720 }
00721
00722
00723
00724 _trivialIndexP->setElementAt( oldCellIdx,
00725 CdbBdbSPartitionCell( theNewRef->cell( ),
00726 theNewRef->id( ),
00727 theNewRef ));
00728
00729
00730
00731 if( ! updateIndexOnly ) {
00732
00733
00734
00735
00736 if( CdbStatus::Success != _collectionP->remove( theNewRef->id( ))) {
00737
00738 cout << errorStr << endl
00739 << " Failed to remove old parition object out of the collection." << endl
00740 << " PARTITION ID: " << theNewRef->id( ) << endl;
00741
00742 result = CdbStatus::Error;
00743
00744 break;
00745 }
00746
00747
00748
00749 if( CdbStatus::Success != _collectionP->insert( theNewRef )) {
00750
00751 cout << errorStr << endl
00752 << " Failed to insert new parition object into the collection." << endl
00753 << " PARTITION ID: " << theNewRef->id( ) << endl;
00754
00755 result = CdbStatus::Error;
00756
00757 break;
00758 }
00759 }
00760
00761
00762
00763 result = CdbStatus::Success;
00764
00765 } while( false );
00766
00767 return result;
00768 }
00769
00770 CdbStatus
00771 CdbBdbSPartitionsLayoutP::find( d_UShort theId,
00772 BdbRef( CdbBdbSPartitionBaseP )& theRef ) const
00773 {
00774 return _collectionP->find( theId,
00775 theRef );
00776 }
00777
00778 CdbStatus
00779 CdbBdbSPartitionsLayoutP::find( const BdbTime& theValidityTime,
00780 const BdbTime& theInsertionTime,
00781 BdbRef( CdbBdbSPartitionBaseP )& theRef ) const
00782 {
00783 CdbStatus result = CdbStatus::NotFound;
00784 {
00785
00786
00787 d_ULong num = _trivialIndexP->size( );
00788 for( d_ULong i = 0; i < num; ++i ) {
00789
00790 CdbBdbSPartitionCell pCell = _trivialIndexP->elementAt( i );
00791
00792 if( pCell.cell.in( theValidityTime,
00793 theInsertionTime )) {
00794
00795 theRef = pCell.partition;
00796
00797 result = CdbStatus::Success;
00798 break;
00799 }
00800 }
00801 }
00802 return result;
00803 }
00804
00805 CdbStatus
00806 CdbBdbSPartitionsLayoutP::find( const BdbTime& theValidityTime,
00807 BdbRef( CdbBdbSPartitionBaseP )& theRef ) const
00808 {
00809 CdbStatus result = CdbStatus::NotFound;
00810 {
00811
00812
00813 d_ULong num = _trivialIndexP->size( );
00814 if( num > 0 ) {
00815
00816
00817
00818
00819
00820
00821 int first = num - 1;
00822 assert( first >= 0 );
00823
00824
00825 for( int i = first; i >= 0; --i ) {
00826
00827 CdbBdbSPartitionCell pCell = _trivialIndexP->elementAt( i );
00828
00829 if( pCell.cell.inValidityRange( theValidityTime ) &&
00830 ( BdbTime::plusInfinity == pCell.cell.endInsertion )) {
00831
00832 theRef = pCell.partition;
00833
00834 result = CdbStatus::Success;
00835 break;
00836 }
00837 }
00838 }
00839 }
00840 return result;
00841 }
00842 CdbStatus
00843 CdbBdbSPartitionsLayoutP::topmost( const BdbTime& theValidityTime,
00844 BdbRef( CdbBdbSPartitionBaseP )& theRef ) const
00845 {
00846 CdbStatus result = CdbStatus::NotFound;
00847 {
00848
00849
00850 d_ULong num = _trivialIndexP->size( );
00851 if( num > 0 ) {
00852
00853
00854
00855
00856
00857
00858 int first = num - 1;
00859 assert( first >= 0 );
00860
00861
00862 for( int i = first; i >= 0; --i ) {
00863
00864 CdbBdbSPartitionCell pCell = _trivialIndexP->elementAt( i );
00865
00866 if( pCell.cell.inValidityRange( theValidityTime )) {
00867
00868 theRef = pCell.partition;
00869
00870 result = CdbStatus::Success;
00871 break;
00872 }
00873 }
00874 }
00875 }
00876 return result;
00877 }
00878
00879 CdbStatus
00880 CdbBdbSPartitionsLayoutP::next( const BdbTime& theValidityTime,
00881 BdbRef( CdbBdbSPartitionBaseP )& theRef ) const
00882 {
00883 assert( !BdbIsNull(theRef));
00884
00885 CdbStatus result = CdbStatus::NotFound;
00886 {
00887
00888
00889
00890
00891
00892
00893
00894 d_ULong num = _trivialIndexP->size( );
00895 if( num > 0 ) {
00896
00897
00898
00899
00900 bool idxIsFound = false;
00901 d_ULong idx = 0;
00902 {
00903 int first = num - 1;
00904 assert( first >=0 );
00905
00906
00907 for( int i = first; i >= 0; --i ) {
00908
00909 CdbBdbSPartitionCell pCell = _trivialIndexP->elementAt( i );
00910
00911 if( theRef == pCell.partition ) {
00912 idxIsFound = true;
00913 idx = i;
00914 break;
00915 }
00916 }
00917 }
00918
00919
00920
00921
00922 if( idxIsFound && ( 0 != idx )) {
00923
00924 int first = idx - 1;
00925 assert( first >= 0 );
00926
00927
00928 for( int i = first; i >= 0; --i ) {
00929
00930 CdbBdbSPartitionCell pCell = _trivialIndexP->elementAt( i );
00931
00932 if( pCell.cell.inValidityRange( theValidityTime )) {
00933
00934 theRef = pCell.partition;
00935
00936 result = CdbStatus::Success;
00937 break;
00938 }
00939 }
00940 }
00941 }
00942 }
00943 return result;
00944 }
00945
00946 CdbStatus
00947 CdbBdbSPartitionsLayoutP::close( d_UShort theId )
00948 {
00949 const char* fatalStr = "CdbBdbSPartitionsLayoutP::close() - FATAL ERROR.";
00950
00951 ooUpdate( );
00952
00953
00954
00955 BdbRef( CdbBdbSPartitionBaseP ) ref;
00956
00957 CdbStatus result = find( theId,
00958 ref );
00959 if( CdbStatus::Success != result ) {
00960 return result;
00961 }
00962
00963
00964
00965 d_ULong foundIndex = 0;
00966 bool indexWasFound = false;
00967 {
00968 d_ULong num = _trivialIndexP->size( );
00969 for( d_ULong i = 0; i < num; ++i ) {
00970
00971 CdbBdbSPartitionCell pCell = _trivialIndexP->elementAt( i );
00972
00973 if( theId == pCell.id ) {
00974
00975 if( ref != pCell.partition ) {
00976 cout << fatalStr << endl
00977 << " The trivial index is not compatible with the collection of partitions." << endl;
00978 assert( 0 );
00979
00980 } else {
00981 foundIndex = i;
00982 indexWasFound = true;
00983 }
00984 break;
00985 }
00986 }
00987 }
00988 if( ! indexWasFound ) {
00989
00990 cout << fatalStr << endl
00991 << " The trivial index is not compatible with the collection of partitions." << endl;
00992
00993 assert( 0 );
00994
00995 return CdbStatus::Error;
00996 }
00997
00998
00999
01000 _trivialIndexP->setElementAt( foundIndex,
01001 CdbBdbSPartitionCell( ref->cell( ),
01002 theId,
01003 ref ));
01004 return CdbStatus::Success;
01005 }
01006
01007 CdbItr< d_UShort >
01008 CdbBdbSPartitionsLayoutP::iterator( ) const
01009 {
01010 return _collectionP->iterator_identifiers( );
01011 }
01012
01013 CdbItr< CdbBdbSPartitionInterval >
01014 CdbBdbSPartitionsLayoutP::iterator( const BdbTime& theInsertionTime,
01015 const BdbTime& theBeginValidityTime,
01016 const BdbTime& theEndValidityTime ) const
01017 {
01018 const char* debugStr = "CdbBdbSPartitionsLayoutP::iterator()";
01019
01020 assert( !BdbIsNull(_trivialIndexP));
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032 const CdbBdbSCell iteratorCell( theBeginValidityTime,
01033 theEndValidityTime,
01034 BdbTime::minusInfinity,
01035 theInsertionTime );
01036
01037
01038 if( CdbEnvironment::getDebugMode( ) != 0 )
01039 cout << debugStr << endl
01040 << "{" << endl
01041 << "iteratorCell ->" << endl
01042 << iteratorCell << endl
01043 << "}" << endl;
01044
01045
01046 std::vector<CdbBdbSPartitionCell> cells;
01047
01048 d_ULong num = _trivialIndexP->size( );
01049 for( d_ULong i = 0; i < num; ++i ) {
01050 CdbBdbSPartitionCell pc = _trivialIndexP->elementAt( i );
01051
01052
01053 if( CdbEnvironment::getDebugMode( ) != 0 )
01054 cout << debugStr << endl
01055 << "{" << endl
01056 << "pc.cell ->" << endl
01057 << pc.cell << endl
01058 << "}" << endl;
01059
01060
01061 if( iteratorCell.overlap( pc.cell )) {
01062
01063 if( CdbEnvironment::getDebugMode( ) != 0 )
01064 cout << debugStr << endl
01065 << "{" << endl
01066 << "'pc.cell' overlaps with 'iteratorCell'" << endl
01067 << "}" << endl;
01068
01069 cells.insert( cells.begin( ),
01070 pc );
01071 }
01072 }
01073
01074
01075
01076
01077 return CdbItr< CdbBdbSPartitionInterval >( new CdbBdbSPartitionIntervalItr( cells,
01078 theBeginValidityTime,
01079 theEndValidityTime ));
01080 }
01081
01082 void
01083 CdbBdbSPartitionsLayoutP::dump( ostream& o ) const
01084 {
01085 o << "TRIVIAL INDEX: " << _trivialIndexP.sprint( ) << endl
01086 << "COMPLEX INDEX: " << _complexIndexP.sprint( ) << endl
01087 << endl;
01088
01089 _collectionP->dump( o );
01090 }
01091
01092
01093
01094