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

Search | Site Map .

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

/BdbCond/BdbIntervalItr.cc

Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 //
00003 // File and Version Information:
00004 //      $Id: BdbIntervalItr.cc,v 1.6 2002/08/07 21:45:26 gapon Exp $
00005 //
00006 // Description:
00007 //      Class BdbIntervalItr. 
00008 //      This class has an iterator semantics. It provides an easier way
00009 //      to iterate through intervals in a interval container.
00010 //
00011 // Environment:
00012 //      Software developed for the BaBar Detector at the SLAC B-Factory.
00013 //
00014 // Author List:
00015 //      Igor A. Gaponenko       Original Author
00016 //
00017 // Copyright Information:
00018 //      Copyright (C) 1999      Lawrence Berkeley Laboratory
00019 //
00020 //-----------------------------------------------------------------------------
00021 
00022 // -------------------------
00023 // -- This Class's Header --
00024 // -------------------------
00025 
00026 #include "BdbCond/BdbIntervalItr.hh"
00027 
00028 // ---------------
00029 // -- C Headers --
00030 // ---------------
00031 
00032 extern "C" {
00033 #include <assert.h>
00034 #include <ctype.h>
00035 #include <stddef.h>
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 }
00040 
00041 // -----------------
00042 // -- C++ Headers --
00043 // -----------------
00044 
00045 #include <iostream.h>
00046 
00047 // ---------------------------------
00048 // -- Collaborating Class Headers --
00049 // ---------------------------------
00050 
00051 #include "BdbCond/BdbCondErrors.hh"
00052 #include "BdbCond/BdbIntervalR.hh"
00053 #include "BdbCond/BdbIntervalGene.hh"
00054 #include "BdbTime/BdbTime.hh"
00055 #include "ErrLogger/ErrLog.hh"
00056 
00057 // --------------------------------------------------------------------------
00058 // -- Local Macros, Typedefs, Structures, Unions, and Forward Declarations --
00059 // --------------------------------------------------------------------------
00060 
00061 static const char rcsid[] = "$Id: BdbIntervalItr.cc,v 1.6 2002/08/07 21:45:26 gapon Exp $";
00062 
00063 // ------------------
00064 // -- Constructors --
00065 // ------------------
00066 
00067 BdbIntervalItr::BdbIntervalItr( ) :
00068     _db((BdbObsoleteDatabase*) 0)
00069 {
00070     clearContext( );
00071 }
00072 
00073 BdbIntervalItr::BdbIntervalItr( const BdbIntervalItr& theItr )
00074 {
00075     _direction   = theItr._direction;
00076     _nextH       = theItr._nextH;
00077     _topmostH    = theItr._topmostH;
00078     _detector    = theItr._detector;
00079     _container   = theItr._container;
00080     _revisionId  = theItr._revisionId;
00081     _beginTime   = theItr._beginTime;
00082     _db          = new BdbObsoleteDatabase( theItr._detector );
00083     _initialized = theItr._initialized;
00084 }
00085 
00086 // ----------------
00087 // -- Destructor --
00088 // ----------------
00089 
00090 BdbIntervalItr::~BdbIntervalItr( )
00091 {
00092     clearContext( );
00093 }
00094 
00095 // ----------------
00096 // -- Operations --
00097 // ----------------
00098 
00099 BdbIntervalItr&
00100 BdbIntervalItr::operator=( const BdbIntervalItr& theItr )
00101 {
00102     _direction   = theItr._direction;
00103     _nextH       = theItr._nextH;
00104     _topmostH    = theItr._topmostH;
00105     _detector    = theItr._detector;
00106     _container   = theItr._container;
00107     _revisionId  = theItr._revisionId;
00108     _beginTime   = theItr._beginTime;
00109     _db          = new BdbObsoleteDatabase( theItr._detector );
00110     _initialized = theItr._initialized;
00111 
00112     return *this;
00113 }
00114 
00115 BdbIntervalItr::operator BdbIntervalBase&( ) const
00116 {
00117     return *_nextH;
00118 }
00119 
00120 BdbIntervalItr::operator BdbHandle(BdbInterval)&( ) const
00121 {
00122     return (BdbHandle(BdbIntervalR)&) _nextH;
00123 }
00124 
00125 BdbIntervalItr::operator BdbHandle(BdbIntervalR)&( ) const
00126 {
00127     return (BdbHandle(BdbIntervalR)&) _nextH;
00128 }
00129 
00130 // ----------------
00131 // -- Operations --
00132 // ----------------
00133 
00134 bool
00135 BdbIntervalItr::setBaseline( const char*    theDetector,
00136                              const char*    theContainer,
00137                              const BdbTime& theBeginTime )
00138 {
00139     const char* errorString = "BdbIntervalItr::setBaseline( ) -- error.";
00140 
00141   // Clear previous context.
00142 
00143     clearContext( );
00144 
00145   // Create the database.
00146 
00147     _db = new BdbObsoleteDatabase( theDetector );
00148 
00149   // Try specified parameters.
00150 
00151     BdbHandle(BdbIntervalR) theIntervalH;
00152     BdbStatus status;
00153 
00154     status = getFirstBaselineInterval( theIntervalH,
00155                                        theContainer,
00156                                        theBeginTime );
00157     if( BdbcSuccess != status ) {
00158         ErrMsg(error) << errorString << endl
00159                       << "    Unable to initialize iterator with specified parameters." << endl
00160                       << "        Detector:   " << theDetector << endl
00161                       << "        Container:  " << theContainer << endl
00162                       << "        Begin time: " << theBeginTime << endmsg;
00163         return false;
00164     }
00165 
00166   // Set the internal context.
00167 
00168     _direction   = DIRECTION_BASELINE;
00169     _detector    = theDetector;
00170     _container   = theContainer;
00171     _beginTime   = theBeginTime;
00172 
00173     return true;
00174 }
00175 
00176 bool
00177 BdbIntervalItr::setTopmost(  const char*    theDetector,
00178                              const char*    theContainer,
00179                              const BdbTime& theBeginTime  )
00180 {
00181     const char* errorString = "BdbIntervalItr::setTopmost( ) -- error.";
00182 
00183   // Clear previous context.
00184 
00185     clearContext( );
00186 
00187   // Create the database.
00188 
00189     _db = new BdbObsoleteDatabase( theDetector );
00190 
00191   // Try specified parameters.
00192 
00193     BdbHandle(BdbIntervalR) theIntervalH;
00194     BdbStatus status;
00195 
00196     status = getFirstTopmostInterval( theIntervalH,
00197                                       theContainer,
00198                                       theBeginTime );
00199     if( BdbcSuccess != status ) {
00200         ErrMsg(error) << errorString << endl
00201                       << "    Unable to initialize iterator with specified parameters." << endl
00202                       << "        Detector:   " << theDetector << endl
00203                       << "        Container:  " << theContainer << endl
00204                       << "        Begin time: " << theBeginTime << endmsg;
00205         return false;
00206     }
00207 
00208   // Set the internal context.
00209 
00210     _direction   = DIRECTION_TOPMOST;
00211     _detector    = theDetector;
00212     _container   = theContainer;
00213     _beginTime   = theBeginTime;
00214 
00215     return true;
00216 }
00217 
00218 bool
00219 BdbIntervalItr::setRevision( const char*    theDetector,
00220                              const char*    theContainer,
00221                              d_ULong        theRevisionId,
00222                              const BdbTime& theBeginTime )
00223 {
00224     const char* errorString = "BdbIntervalItr::setRevision( ) -- error.";
00225 
00226   // Clear previous context.
00227 
00228     clearContext( );
00229 
00230   // Create the database.
00231 
00232     _db = new BdbObsoleteDatabase( theDetector );
00233 
00234   // Try specified parameters.
00235 
00236     BdbHandle(BdbIntervalR) theIntervalH;
00237     BdbHandle(BdbIntervalR) theTopmostIntervalH;
00238     BdbStatus status;
00239 
00240     status = getFirstRevisedInterval( theIntervalH,
00241                                       theTopmostIntervalH,
00242                                       theContainer,
00243                                       theRevisionId,
00244                                       theBeginTime );
00245     if( BdbcSuccess != status ) {
00246         ErrMsg(error) << errorString << endl
00247                       << "    Unable to initialize iterator with specified parameters." << endl
00248                       << "        Detector:    " << theDetector << endl
00249                       << "        Container:   " << theContainer << endl
00250                       << "        Revision ID: " << theRevisionId << endl
00251                       << "        Begin time:  " << theBeginTime << endmsg;
00252         return false;
00253     }
00254 
00255   // Set the internal context.
00256 
00257     _direction   = DIRECTION_REVISION;
00258     _detector    = theDetector;
00259     _container   = theContainer;
00260     _revisionId  = theRevisionId;
00261     _beginTime   = theBeginTime;
00262 
00263     return true;
00264 }
00265 
00266 bool
00267 BdbIntervalItr::next( )
00268 {
00269     const char* errorString = "BdbIntervalItr::next( ) -- error.";
00270 
00271     bool result = false;
00272 
00273     BdbHandle(BdbIntervalR) theIntervalH;
00274     BdbHandle(BdbIntervalR) theTopmostIntervalH;
00275     BdbStatus status;
00276 
00277   // The operation depends on a direction of the iteration.
00278 
00279     switch( _direction ) {
00280 
00281     case DIRECTION_BASELINE:
00282 
00283         if( ! _initialized ) {
00284 
00285           // Get the first BASELINE interval.
00286 
00287             status = getFirstBaselineInterval( _nextH,
00288                                                _container,
00289                                                _beginTime );
00290             if( BdbcSuccess != status ) {
00291                 ErrMsg(error) << errorString << endl
00292                               << "    Unable to initialize iterator with specified parameters." << endl
00293                               << "        Detector:   " << (const char*) _detector << endl
00294                               << "        Container:  " << (const char*) _container << endl
00295                               << "        Begin time: " << _beginTime << endmsg;
00296                 _nextH = NULL;
00297                 break;
00298             }
00299 
00300             _initialized = true;
00301 
00302         } else {
00303 
00304           // Get the next BASELINE interval.
00305 
00306             if( ! BdbIsNull( _nextH )) {
00307                 _nextH->getBaselineNext( theIntervalH );
00308                 _nextH = theIntervalH;
00309             }
00310         }
00311 
00312         if( BdbIsNull( _nextH )) {
00313             return false;
00314         } else {
00315             return true;
00316         }
00317 
00318     case DIRECTION_TOPMOST:
00319 
00320         if( ! _initialized ) {
00321 
00322           // Get the first TOPMOST interval.
00323 
00324             status = getFirstTopmostInterval( _nextH,
00325                                               _container,
00326                                               _beginTime );
00327             if( BdbcSuccess != status ) {
00328                 ErrMsg(error) << errorString << endl
00329                               << "    Unable to initialize iterator with specified parameters." << endl
00330                               << "        Detector:   " << (const char*) _detector << endl
00331                               << "        Container:  " << (const char*) _container << endl
00332                               << "        Begin time: " << _beginTime << endmsg;
00333                 _nextH = NULL;
00334                 break;
00335             }
00336 
00337             _initialized = true;
00338 
00339         } else {
00340 
00341           // Get the next TOPMOST interval.
00342 
00343             if( ! BdbIsNull( _nextH )) {
00344                 _nextH->getTopNext( theIntervalH );
00345                 _nextH = theIntervalH;
00346             }
00347         }
00348 
00349         if( BdbIsNull( _nextH )) {
00350             return false;
00351         } else {
00352             return true;
00353         }
00354 
00355     case DIRECTION_REVISION:
00356 
00357         if( ! _initialized ) {
00358 
00359           // Get the first REVISED interval.
00360 
00361             status = getFirstRevisedInterval( _nextH,
00362                                               _topmostH,
00363                                               _container,
00364                                               _revisionId,
00365                                               _beginTime );
00366             if( BdbcSuccess != status ) {
00367                 ErrMsg(error) << errorString << endl
00368                               << "    Unable to initialize iterator with specified parameters." << endl
00369                               << "        Detector:    " << (const char*) _detector << endl
00370                               << "        Container:   " << (const char*) _container << endl
00371                               << "        Revision ID: " << _revisionId << endl
00372                               << "        Begin time:  " << _beginTime << endmsg;
00373                 _nextH = NULL;
00374                 break;
00375             }
00376 
00377             _initialized = true;
00378 
00379         } else {
00380 
00381           // Get the next REVISED interval.
00382 
00383             if( ! BdbIsNull( _nextH )) {
00384 
00385                 status = getNextRevisedInterval( theIntervalH, theTopmostIntervalH );
00386                 if( BdbcSuccess != status ) {
00387                     ErrMsg(error) << errorString << endl
00388                                   << "    Unable to advance iterator with specified parameters." << endl
00389                                   << "        Detector:    " << (const char*) _detector << endl
00390                                   << "        Container:   " << (const char*) _container << endl
00391                                   << "        Revision ID: " << _revisionId << endl
00392                                   << "        Begin time:  " << _beginTime << endmsg;
00393                     _nextH = NULL;
00394                     break;
00395                 }
00396                 _nextH    = theIntervalH;
00397                 _topmostH = theTopmostIntervalH;
00398             }
00399         }
00400 
00401         if( BdbIsNull( _nextH )) {
00402             return false;
00403         } else {
00404             return true;
00405         }
00406 
00407     default:
00408     
00409         ErrMsg(error) << errorString << endl
00410                       << "    The iterator was not set. Use corresponding ::setXXX() method" << endl
00411                       << "    in order to select iteration direction and parameters." << endmsg;             
00412         break;
00413     }
00414 
00415   // We set this flag in order to be sure that we have properly
00416   // initialized context.
00417 
00418     if( result ) {
00419         clearContext( );
00420     }
00421 
00422     return result;
00423 }
00424 
00425 // -----------------------------------------------------------------
00426 // This operation just resets an iterator context to the state right
00427 // after calling any of setXXX methods thus ensuring that
00428 // the next ::next() will begin from the first element.
00429 // -----------------------------------------------------------------
00430 
00431 void
00432 BdbIntervalItr::reset( )
00433 {
00434     _nextH       = NULL;
00435     _initialized = false;
00436 }
00437 
00438 void
00439 BdbIntervalItr::clearContext( )
00440 {
00441     _direction   = DIRECTION_UNKNOWN;
00442     _nextH       = NULL;
00443     _topmostH    = NULL;
00444     _detector    = (char*) 0;
00445     _container   = (char*) 0;
00446     _revisionId  = BdbCondRevision::BASELINE;
00447     _beginTime   = BdbTime::minusInfinity;
00448     delete _db;
00449     _initialized = false;
00450 }
00451 
00452 BdbStatus
00453 BdbIntervalItr::getFirstBaselineInterval( BdbHandle(BdbIntervalR)& theIntervalH,
00454                                           const char*              theContainer,
00455                                           const BdbTime&           theBeginTime )
00456 {
00457     const char* errorString = "BdbIntervalItr::getFirstBaselineInterval( ) -- error.";
00458 
00459   // Fetch the BASELINE interval for specified time to be sure
00460   // that a valid database and container name were specified.
00461   //
00462   // NOTE: This operation will also verify if we have a "revised"
00463   //       container.
00464   //
00465   // NOTE: We explicitly fetch the FIRST interval if the "-oo" is specified.
00466 
00467     BdbStatus status;
00468 
00469     if( BdbTime::minusInfinity == theBeginTime ) {
00470         status = _db->firstInterval( theIntervalH, theContainer );
00471     } else {
00472         status = _db->getBaselineInterval( theIntervalH, theContainer, theBeginTime );
00473     }
00474     if( BdbcSuccess != status ) {
00475         ErrMsg(error) << errorString << endl
00476                       << "    Unable to locate BASELINE interval." << endmsg;
00477     }
00478 
00479     return status;
00480 }
00481 
00482 BdbStatus
00483 BdbIntervalItr::getFirstTopmostInterval( BdbHandle(BdbIntervalR)& theIntervalH,
00484                                          const char*              theContainer,
00485                                          const BdbTime&           theBeginTime )
00486 {
00487     const char* errorString = "BdbIntervalItr::getFirstTopmostInterval( ) -- error.";
00488 
00489   // Fetch the TOPMOST interval for specified time to be sure
00490   // that a valid database and container name were specified.
00491   //
00492   // NOTE: This operation will also verify if we have a "revised"
00493   //       container.
00494   //
00495   // NOTE: We explicitly fetch the FIRST interval if the "-oo" is specified.
00496 
00497     BdbStatus status;
00498 
00499     if( BdbTime::minusInfinity == theBeginTime ) {
00500         status = _db->firstInterval( theIntervalH, theContainer );
00501     } else {
00502         status = _db->getTopmostInterval( theIntervalH, theContainer, theBeginTime );
00503     }
00504     if( BdbcSuccess != status ) {
00505         ErrMsg(error) << errorString << endl
00506                       << "    Unable to locate TOPMOST interval." << endmsg;
00507     }
00508 
00509     return status;
00510 }
00511 
00512 BdbStatus
00513 BdbIntervalItr::getFirstRevisedInterval( BdbHandle(BdbIntervalR)& theIntervalH,
00514                                          BdbHandle(BdbIntervalR)& theTopmostIntervalH,
00515                                          const char*              theContainer,
00516                                          d_ULong                  theRevisionId,
00517                                          const BdbTime&           theBeginTime )
00518 {
00519     const char* errorString = "BdbIntervalItr::getFirstRevisedInterval( ) -- error.";
00520 
00521   // Fetch the REVISED interval for specified time and revision to be sure
00522   // that a valid database and container name were specified.
00523   //
00524   // NOTE: This operation will also verify if we have a "revised"
00525   //       container.
00526   //
00527   // NOTE: We explicitly fetch the FIRST interval if the "-oo" is specified.
00528 
00529     BdbStatus status;
00530 
00531     if( BdbTime::minusInfinity == theBeginTime ) {
00532         status = _db->firstInterval( theIntervalH, theContainer );
00533     } else {
00534         status = _db->getRevisedInterval( theIntervalH, theContainer, theBeginTime, theRevisionId );
00535     }
00536     if( BdbcSuccess != status ) {
00537         ErrMsg(error) << errorString << endl
00538                       << "    Unable to locate REVISED interval." << endmsg;
00539         return status;
00540     }
00541 
00542     status = _db->getTopmostInterval( theTopmostIntervalH, theContainer, theBeginTime );
00543     if( BdbcSuccess != status ) {
00544         ErrMsg(error) << errorString << endl
00545                       << "    Unable to locate TOPMOST interval." << endmsg;
00546         return status;
00547     }
00548 
00549     return status;
00550 }
00551 
00552 BdbStatus
00553 BdbIntervalItr::getNextRevisedInterval( BdbHandle(BdbIntervalR)& theIntervalH,
00554                                         BdbHandle(BdbIntervalR)& theTopmostIntervalH  )
00555 {
00556     const char* errorString = "BdbIntervalItr::getNextRevisedInterval( ) -- error.";
00557 
00558     BdbStatus status;
00559 
00560   // Some preliminary checks.
00561 
00562     if( BdbIsNull( _nextH )) {
00563         theIntervalH = _nextH;
00564         return BdbcSuccess;
00565     }
00566 
00567     if( BdbIsNull( _topmostH )) {
00568         ErrMsg(error) << errorString << endl
00569                       << "    Internal bug was detected." << endmsg;
00570         return BdbcError;
00571     }
00572 
00573   // The following loop will proceed along the TOPMOST intervals
00574   // until different then the current REVISED interval is met.
00575 
00576     BdbHandle(BdbIntervalR) theNextTopmostIntervalH;
00577     theNextTopmostIntervalH = _topmostH;
00578 
00579     do {
00580 
00581       // We need to make next try from the begin time of the next
00582       // TOPMOST interval wich provides us the next split point.
00583 
00584         theNextTopmostIntervalH->getTopNext( theTopmostIntervalH );
00585         if( BdbIsNull( theTopmostIntervalH )) {
00586             break;
00587         }
00588         theNextTopmostIntervalH = theTopmostIntervalH;
00589 
00590       // Now we will locate the desired REVISED interval
00591 
00592         status = _db->getRevisedInterval( theIntervalH,
00593                                           _container,
00594                                           theTopmostIntervalH->getBeginTime( ),
00595                                           _revisionId );
00596         if( BdbcSuccess != status ) {
00597             ErrMsg(error) << errorString << endl
00598                           << "    Unable to locate REVISED interval." << endmsg;
00599             return status;
00600         }
00601         if( BdbIsNull( theIntervalH )) {
00602             break;
00603         }
00604  
00605     } while( theIntervalH == _nextH );
00606 
00607     return BdbcSuccess;
00608 }
00609 
00610 /////////////////
00611 // End Of File //
00612 /////////////////

 


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

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