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  

/BdbEventStore/BdbLocateDb.cc

Go to the documentation of this file.
00001 //--------------------------------------------------------------------------
00002 // File and Version Information:
00003 //      $Id: BdbLocateDb.cc,v 1.36.2.1 2002/09/03 18:30:27 becla Exp $
00004 //
00005 // Description:
00006 //      This class collectes the databases associated to the objects of 
00007 //      collections or domains.
00008 //
00009 // Environment:
00010 //      Software developed for the BaBar Detector at the SLAC B-Factory.
00011 //
00012 // Author List:
00013 //      Jean-Noel Albert    First author
00014 //      Moreno Marzolla     Added support for collection MetaData
00015 //
00016 // Copyright Information:
00017 //      Copyright (C) 1998      Laboratoire de l'Accelerateur Lineaire
00018 //      Copyright (C) 2000      INFN Padova
00019 //
00020 //------------------------------------------------------------------------
00021 
00022 //------------------
00023 // Class's Header --
00024 //------------------
00025 #include "BdbEventStore/BdbLocateDb.hh"
00026 #include "BbrStdUtils/BbrStdDeleteObject.hh"
00027 
00028 //-------------
00029 // C Headers --
00030 //-------------
00031 extern "C" {
00032 #include <stdlib.h>
00033 #include <regex.h>
00034 #include <string.h>
00035 #include <strings.h>
00036 }
00037 
00038 //---------------
00039 // C++ Headers --
00040 //---------------
00041 
00042 //-----------------------
00043 // BaBar class headers --
00044 //-----------------------
00045 #include "BdbApplication/BdbDomain.hh"
00046 #include "BdbTrees/BdbDbRegistrator.hh"
00047 #include "BdbEventStore/BdbEventStore.hh"
00048 #include "BdbEventStore/BdbCollectionTIterator.hh"
00049 #include "BdbUtil/BdbCollectRef.hh"
00050 #include "BdbTrees/BdbTreeNode.hh"
00051 #include "BdbTrees/BdbTreeNodeIterator.hh"
00052 #include "BdbEvent/BdbEventT.hh"
00053 #include "BdbEvent/BdbEvent.hh"
00054 #include "BdbEvent/BdbEvent_001.hh"
00055 #include "BdbEventStore/BdbDistMetaDataMgr.hh"
00056 #include <algorithm>
00057 
00058 #ifdef   BABAR_COMP_INST
00059 #undef   BABAR_COMP_INST
00060 #endif
00061 #include "BdbEventStore/BdbCollectionTCollTIterator.hh"
00062 
00063 //--------------------
00064 // Local definition --
00065 //--------------------
00066 #define INTERNAL_PATTERNS 2
00067 
00068 //-------------------
00069 // Local variables --
00070 //-------------------
00071 // Keep the list of the databases already checked
00072 //      (``Invalid'' databases can be found after a partial transfer)
00073 //  This is faster than testing each time the validity of the object
00074 static set<BdbCollectRef*, babar::Collection::PtrLess> InvRefs, ValRefs;
00075 
00076 ///////////////////////////////////////////////////////////////////////////////
00077 //
00078 // Debug functions
00079 
00080 //#define BDBSCANDB_TRACE
00081 
00082 #ifndef BDBSCANDB_TRACE
00083 
00084 #define objectDebug(type,obj)
00085 #define collDebug(type,obj)
00086 
00087 #else
00088 
00089 #define objectDebug(type,obj)   objectInfo(type,obj)
00090 #define collDebug(obj,lvl)      collInfo(obj,lvl)
00091 
00092 static int traceLevel()
00093 {
00094     static int trcLevel = -2;
00095 
00096     if (trcLevel == -2) {
00097         // Fly debug
00098         char* trcenv = getenv("BDBSCANDB_TRACE");
00099         if (trcenv == 0)
00100             trcLevel = -1;              // No trace
00101         else if (*trcenv == 'F')
00102             trcLevel = 1;               // Full trace
00103         else if (*trcenv == 'C')
00104             trcLevel = 2;               // Collection only
00105         else
00106             trcLevel = 0;               // Minimal trace
00107     }
00108     return trcLevel;
00109 }
00110 
00111 static void objectInfo (const char* trace_type, const BdbRef(BdbPersObj)& obj)
00112 {
00113     BdbRef(BdbDBObj) db;
00114     BdbRef(BdbContObj) cont;
00115 
00116     switch (traceLevel()) {
00117         case 0 :
00118             cout << trace_type << ": " << obj.get_DB()
00119                  << "-" << obj.get_OC() 
00120                  << "-" << obj.get_page()
00121                  << "-" << obj.get_slot() << endl;
00122             break;
00123 
00124         case 1:
00125             cout << "Object id: " << obj.sprint()
00126                  << " type name: " << obj.typeName()
00127                  << " type number: " << obj.typeN() << endl;    
00128 
00129             obj.containedIn(cont);
00130             cont.containedIn(db);
00131             cout << " Container Id: " << cont.sprint()
00132                  << " Database Id: " << db.sprint()
00133                  << " name: " << db.name() << endl;
00134             break;
00135     }
00136 }
00137 
00138 static void collInfo(const BdbRef(BdbCollectionP)& coll, int level)
00139 {
00140     if (traceLevel() == 2) {
00141         cout << "Collection level: " << level << endl
00142              << "\tCollection name: " << coll->name() << endl
00143              << "\tFull name: " << coll->pathName() << endl
00144              << "\tNumber of events: " << coll->size() << endl
00145              << "\tNumber of items: " << coll->collections() << endl
00146              << "\tOID: " << coll.sprint() << endl
00147              << "\ttype name: " << coll.typeName() << endl
00148              << "\ttype number: " << coll.typeN() << endl;
00149     }
00150 }
00151 #endif
00152 
00153 ///////////////////////////////////////////////////////////////////////////////
00154 //
00155 // Internal functions
00156 
00157 d_Boolean BdbLocateDb::addDb(int dbid)
00158 {
00159     BdbRef(BdbDBObj) db;
00160     db.set_DB(dbid);
00161     BdbCollectRef dbCR (db);
00162 
00163     if (InvRefs.find(&dbCR)!=InvRefs.end())
00164         return d_False;
00165     else if (ValRefs.find(&dbCR)==ValRefs.end()) {
00166         if (!db.isValid()) {
00167             InvRefs.insert(new BdbCollectRef(dbCR));
00168             return d_False;
00169         }
00170         else
00171           ValRefs.insert(new BdbCollectRef(dbCR));
00172     }
00173 
00174     if (_rejs.find(&dbCR)!=_rejs.end())
00175         return d_False;
00176 
00177     if (_dbs.find(&dbCR)==_dbs.end()) {
00178         int p;
00179         for (p = 0; p < _nbexcls; p++) {
00180             if (regexec((regex_t*)_excludes[p], db.name(), 0, 0, 0) == 0) {
00181                 _rejs.insert(new BdbCollectRef(dbCR));
00182                 return d_False;
00183             }
00184         }
00185         if (_nbpats > INTERNAL_PATTERNS) {
00186             for (p = 0; p < _nbpats; p++) {
00187                 if (regexec((regex_t*)_patterns[p], db.name(), 0, 0, 0) == 0) {
00188                     _dbs.insert(new BdbCollectRef(dbCR));
00189                     return d_True;
00190                 }
00191             }
00192             _rejs.insert(new BdbCollectRef(dbCR));
00193             return d_False;
00194         }
00195         else {
00196             _dbs.insert(new BdbCollectRef(dbCR));
00197             return d_True;
00198         }
00199     }
00200     return d_True;
00201 }
00202 
00203 d_Boolean BdbLocateDb::checkItem(const BdbRef(BdbPersObj)& item)
00204 {
00205     // Create ``dummy'' database and container references using the first
00206     // part of the item ID.
00207     //  By definition, the Objectivity OID are:
00208     //          Database #, Container #, Page # and Slot #
00209     //  For a database, all the numbers but the first one are 0.
00210     //
00211     // The correct sequence would be:
00212     //  BdbRef(ooContObj) cont;
00213     //  item.containedIn(cont);
00214     //  BdbRef(BdbDBObj) db;
00215     //  cont.containedIn(db);
00216     //
00217     // but the <item.containedIn> is a handle call.
00218     // The <item> is pined in memory. 
00219     // The database *has* to be available.
00220     // If the databases are in the HPSS, the ``correct'' sequence
00221     // implies to down load *each* database !
00222     //
00223     // By creating a pseudo-reference, the following sequence
00224     // works only with the database catalog and does not
00225     // access the physical databases.
00226 
00227     if (item == 0)
00228         return d_False;                 // Invalid oid ?
00229 
00230     _theMgr.addDB( item ); // Update the metaDataManager object
00231 
00232     if (!addDb(item.get_DB()))
00233         return d_False;
00234 
00235     if (!_keepconts)
00236         return d_True;
00237 
00238     BdbRef(BdbContObj) cont;
00239     cont.set_DB(item.get_DB());
00240     cont.set_OC(item.get_OC());
00241     BdbCollectRef contCR (cont);
00242 
00243     if (InvRefs.find(&contCR)!=InvRefs.end())
00244         return d_False;
00245     else if (ValRefs.find(&contCR)==ValRefs.end()) {
00246         if (!item.isValid()) {
00247             cont = item.containedIn();
00248             if (cont == 0) {
00249                 InvRefs.insert(new BdbCollectRef(contCR));
00250                 return d_False;
00251             }
00252         }
00253         else
00254             ValRefs.insert(new BdbCollectRef(contCR));
00255     }
00256 
00257     cont = item.containedIn();
00258     contCR = cont;
00259     if (_conts.find(&contCR)==_conts.end())
00260       _conts.insert(new BdbCollectRef(cont));
00261 
00262     return d_True;
00263 }
00264 
00265 void BdbLocateDb::iterateOverHeader( const BdbGenericHdrT& hdr )
00266 {
00267     // Iterate over all the items of the header
00268    BdbRef( BdbPersObj )* objects ;
00269    const size_t numberObjects( hdr.getPersObjs( objects ) ) ;
00270    for( size_t object( 0 ) ;
00271         numberObjects != object ;
00272         object++ ) {
00273       objectDebug("Item", objects[ object ] );
00274       checkItem( objects[ object ]);
00275    }
00276    if ( 0 != numberObjects ) {
00277      delete objects ;
00278    }
00279 }
00280 
00281 void BdbLocateDb::iterateOverCollection(BdbAbsCollectionT<BdbEventT>* collection,
00282                                         int level)
00283 {
00284     // Persistent object associated to the collection
00285     BdbHandle(BdbCollectionP) collP = collection->persistent();
00286     if (collP != 0) {
00287 #ifdef BDBSCANDB_TRACE
00288         if (traceLevel() == 2)
00289             collDebug(collP, level);
00290 #endif
00291         checkItem(collP);
00292     }
00293 
00294     // Iterate over the embeded collections
00295     BdbAbsCollectionT<BdbEventT>* embededColl = 0;
00296     BdbCollectionTCollTIterator collItr (*collection);
00297     while (BdbcSuccess == collItr.next(embededColl)) {
00298         if ( 0 != embededColl ) {
00299             iterateOverCollection(embededColl, level+1);
00300         }
00301     }
00302 }
00303 
00304 ///////////////////////////////////////////////////////////////////////////////
00305 //
00306 // Constructor
00307 
00308 BdbLocateDb::BdbLocateDb (d_Boolean collectContainers)
00309     : _dbit(_dbs.begin()), _contit(_conts.begin()), _invdbit(InvRefs.begin()), _theMgr()
00310 {
00311     _keepconts = collectContainers;
00312 
00313     // List of the filter patterns
00314     _patterns.resize(8);
00315     _nbpats = 0;
00316     _excludes.resize(8);
00317     _nbexcls = 0;
00318 
00319     // Create 2 default patterns for the mandatory Events Store databases (evt & col)
00320     filter(".+_.+_.+_col[0-9]+", d_True);
00321     filter(".+_.+_.+_evt[0-9]+", d_True);
00322 
00323     assert(_nbpats == INTERNAL_PATTERNS);
00324 
00325     // A dummy call to force the loading of the BdbEvent module
00326     int n = ooTypeN(BdbEvent);
00327     int n1 = ooTypeN(BdbEvent_001);
00328 }
00329 
00330 // Destructor
00331 BdbLocateDb::~BdbLocateDb ()
00332 {
00333     clear();
00334     clearFilters();
00335 }
00336 
00337 void BdbLocateDb::reset()
00338 {
00339     _dbit=_dbs.begin();
00340     if (_keepconts)
00341         _contit=_conts.begin();
00342     _invdbit=InvRefs.begin();
00343     _theMgr.clear();
00344 }
00345 
00346 void BdbLocateDb::clear()
00347 {
00348   std::for_each(_dbs.begin(),_dbs.end(),BbrStdDeleteObject());
00349   _dbs.clear();
00350   if (_keepconts){
00351     std::for_each(_conts.begin(),_conts.end(),BbrStdDeleteObject());
00352     _conts.clear();
00353   }
00354   std::for_each(ValRefs.begin(),ValRefs.end(),BbrStdDeleteObject());
00355   ValRefs.clear();
00356   std::for_each(InvRefs.begin(),InvRefs.end(),BbrStdDeleteObject());
00357   InvRefs.clear();
00358   _theMgr.clear();
00359 }
00360 
00361 void BdbLocateDb::clearFilters()
00362 {
00363     // Clear the user patterns, but keep the default ones (col & evt)
00364     int p;
00365     for (p = INTERNAL_PATTERNS; p < _nbpats; p++)
00366         if (_patterns[p] != 0)
00367             delete[] _patterns[p];
00368     _nbpats = INTERNAL_PATTERNS;
00369 
00370     for (p = 0; p < _nbexcls; p++)
00371         if (_excludes[p] != 0)
00372             delete[] _excludes[p];
00373     _nbexcls = 0;
00374 }
00375 
00376 BdbStatus BdbLocateDb::filter(const char* pattern, d_Boolean include)
00377 {
00378     regex_t regex;
00379 
00380     // Compile the regular expression pattern
00381     if (regcomp(&regex, pattern, REG_EXTENDED) != 0) {
00382         fprintf(stderr, "Invalid regular expression <%s>\n", pattern);
00383         return BdbcError;
00384     }
00385     if (include) {
00386         if (_patterns.size() <= _nbpats)
00387             _patterns.resize(_patterns.size() + 8);
00388         _patterns[_nbpats] = new char[sizeof(regex_t)];
00389         memcpy(_patterns[_nbpats], &regex, sizeof(regex_t));
00390         _nbpats++;
00391     }
00392     else {
00393         if (_excludes.size() <= _nbexcls)
00394             _excludes.resize(_excludes.size() + 8);
00395         _excludes[_nbexcls] = new char[sizeof(regex_t)];
00396         memcpy(_excludes[_nbexcls], &regex, sizeof(regex_t));
00397         _nbexcls++;
00398     }
00399 
00400     return BdbcSuccess;
00401 }
00402 
00403 BdbStatus BdbLocateDb::eventFilter(const char* type, d_Boolean include)
00404 {
00405     char pattern[64];
00406 
00407     // Define a regular expression to filter the Events Store databases
00408     sprintf(pattern, ".+_.+_.+_%s[0-9]+", type);
00409     if (BdbcSuccess != filter(pattern, include))
00410         return BdbcError;
00411 
00412     // Define a regular expression to filter the Events Store header databases
00413     sprintf(pattern, ".+_.+_.+_%shdr[0-9]+", type);
00414     if (BdbcSuccess != filter(pattern, include))
00415         return BdbcError;
00416 
00417     return BdbcSuccess;
00418 }
00419 
00420 BdbStatus BdbLocateDb::domainFilter(const char* type, d_Boolean include)
00421 {
00422     char pattern[64];
00423 
00424     // Define a regular expression to filter the non Events Store databases
00425     sprintf(pattern, ".+_%s_%s[0-9]+", type, type);
00426     if (BdbcSuccess != filter(pattern, include))
00427         return BdbcError;
00428 
00429     // Define a regular expression to filter the non Events Store index
00430     sprintf(pattern, ".+_%s_Index", type);
00431     if (BdbcSuccess != filter(pattern, include))
00432         return BdbcError;
00433 
00434     return BdbcSuccess;
00435 }
00436 
00437 BdbStatus BdbLocateDb::patternSelect(const char* pattern)
00438 {
00439     return filter(pattern, d_True);
00440 }
00441 
00442 BdbStatus BdbLocateDb::patternExclude(const char* pattern)
00443 {
00444     return filter(pattern, d_False);
00445 }
00446 
00447 BdbStatus BdbLocateDb::eventSelect(const char* type)
00448 {
00449     return eventFilter(type, d_True);
00450 }
00451 
00452 BdbStatus BdbLocateDb::eventExclude(const char* type)
00453 {
00454     return eventFilter(type, d_False);
00455 }
00456 
00457 BdbStatus BdbLocateDb::domainSelect(const char* type)
00458 {
00459     return domainFilter(type, d_True);
00460 }
00461 
00462 BdbStatus BdbLocateDb::domainExclude(const char* type)
00463 {
00464     return domainFilter(type, d_False);
00465 }
00466 
00467 BdbStatus BdbLocateDb::scanCatalog ()
00468 {
00469     BdbItr(BdbDBObj) dbItr;
00470     if (BdbcSuccess != dbItr.scan(BdbEventStore::instance()->fd()))
00471         return BdbcError;
00472 
00473     while (dbItr.next()) {
00474         if (dbItr.isValid()) {
00475             BdbRef(BdbDBObj) db = (BdbRef(BdbDBObj)) dbItr;
00476             addDb(db.get_DB());
00477         }
00478     }
00479     return BdbcSuccess;
00480 }
00481 
00482 BdbStatus BdbLocateDb::scanCollection (const char* collectionName,
00483                                        d_Boolean trustMetaData,
00484                                        d_Boolean updateMetaData )
00485 {
00486     BdbAbsCollectionT<BdbEventT>* collection = 
00487         BdbEventStore::instance()->collection(collectionName, (*(BdbEventT*)0) );
00488 
00489     if ( 0 == collection ) {
00490         return BdbcError;       // No such collection
00491     }
00492     scan(collection, trustMetaData, updateMetaData );
00493     return BdbcSuccess;
00494 }
00495 
00496 BdbStatus BdbLocateDb::scanDomain (const char* domainName)
00497 {
00498     if (0 == strcasecmp("MetaData", domainName)) {
00499         scanMetaData();
00500         return BdbcSuccess;
00501     }
00502 
00503     for (int dmn = 0; dmn < int(BdbDomain::IllegalDomain); dmn++) {
00504         if (0 == strcasecmp(BdbDomain::domainName(BdbDomain::Domains(dmn)), 
00505                             domainName)) {
00506             scan(BdbDomain::Domains(dmn));
00507             return BdbcSuccess;
00508         }
00509     }
00510     return BdbcError;   // No such domain
00511 }
00512 
00513 int BdbLocateDb::scanMetaData()
00514 {
00515     static const char* metaDbs[] = {
00516         "cfg_clustHintConfig", "con_clustHintConfig",
00517         "evs_clustHintConfig", "evs_treenodes",
00518         "management", "global", "empty"
00519     };
00520     static const int nbDbs = sizeof(metaDbs) / sizeof(metaDbs[0]);
00521 
00522     for (int d = 0; d < nbDbs; d++) {
00523         // Initialize a reference for this database
00524         BdbRef(BdbDBObj) db;
00525         if (BdbcSuccess != db.exist(BdbEventStore::instance()->fd(), metaDbs[d]))
00526             continue;           // Ignore it...
00527 
00528         addDb(db.get_DB());
00529     }
00530 
00531     return _dbs.size();
00532 }
00533 
00534 int BdbLocateDb::scan(BdbDomain::Domains domain)
00535 {
00536     BdbTreeNode domainNode ;
00537     if (BdbcSuccess != domainNode.moveToRootChild(BdbDomain::domainName(domain), 
00538                                                   BdbDbRegistrator::_rootName))
00539         return _dbs.size();
00540 
00541     BdbTreeNodeIterator itrAuth(domainNode) ;
00542     BdbTreeNode authNode ;
00543     while (itrAuth.next(authNode)) {
00544         BdbTreeNodeIterator itrUserName(authNode) ;
00545         BdbTreeNode userNode ;
00546         while (itrUserName.next(userNode)) {
00547             BdbTreeNodeIterator itrCompName(userNode) ;
00548             BdbTreeNode compNode ;
00549             while (itrCompName.next(compNode)) {
00550                 // ooMapItr dbItr (compNode.persistent()->children());
00551                 BdbRef(BdbMap) childrenM = compNode.persistent()->children();
00552                 ooMapItr dbItr (childrenM);
00553                 while (dbItr.next()) {
00554                     const char* dbname = dbItr->name();
00555                     BdbRef(BdbDBObj) db;
00556                     if (BdbcSuccess == db.exist(BdbApplicationOrDomain::activeInstance()->fd(), dbname, oocNoOpen))
00557                         addDb(db.get_DB());
00558                 }
00559             }
00560         }
00561     }
00562 
00563     return _dbs.size();
00564 }
00565 
00566 void BdbLocateDb::scanEvent(const BdbEventT& event, d_Boolean scanSubEvents)
00567 {
00568     checkItem(event.getPersistent());
00569 
00570     if (scanSubEvents) {
00571         BdbRef(BdbEventTag) tag;
00572 
00573         // ugly hack, while deciding how to access Tag in BdbEventT
00574         if (BdbcSuccess == ((BdbRef(BdbEvent)&) event.getPersistent())->tag(tag))
00575             checkItem(tag);
00576 
00577         objectDebug("Event", event.getPersistent());
00578 
00579     // collection that owns the event. The col database is added.
00580 
00581     BdbHandle(BdbPersObj) ownerColl;
00582     if (BdbcSuccess == 
00583         ((BdbRef(BdbEvent)&)event.getPersistent())->owner( (BdbHandle(BdbPersObj)&) ownerColl) ) {
00584       checkItem(ownerColl);
00585     }
00586 
00587         // Iterate over all headers in the event
00588         const char** headerKeys ;
00589         const size_t numberKeys( event.hdrKeys( headerKeys ) ) ;
00590         for( size_t header( 0 ) ;
00591              numberKeys != header ;
00592              header++ ) {
00593            const BdbGenericHdrT hdr( event.findHeader( headerKeys[ header ] ) ) ;
00594 
00595            BdbRef( BdbPersObj ) hdrR( hdr.getPersistent() ) ;
00596            BdbCollectRef dbCR(hdrR.get_DB());
00597            if (InvRefs.find(&dbCR)!=InvRefs.end())
00598               continue;
00599            
00600            // Base not already tested
00601            else if (ValRefs.find(&dbCR)==ValRefs.end()) {
00602               if (hdrR.isValid())
00603                  ValRefs.insert(new BdbCollectRef(dbCR));
00604               else {
00605                  InvRefs.insert(new BdbCollectRef(dbCR));
00606                  continue;
00607               }
00608            }
00609            objectDebug("Header", hdrR);
00610            checkItem(hdrR);
00611 
00612            iterateOverHeader(hdr);
00613            
00614          // cast away const to allow deletion.
00615          delete [] (char*)(headerKeys[ header ]) ;
00616         }
00617         if( 0 != numberKeys ) {
00618            delete [] headerKeys ;
00619         }
00620     }
00621 
00622     // Check the original event
00623     //  Don't iterate over the subevents
00624     BdbRef(BdbEvent) origEvt;
00625     // ugly hack, while deciding how to access Original in BdbEventT
00626     if (BdbcSuccess != ((BdbRef(BdbEvent)&)event.getPersistent())->original(origEvt))
00627         return;
00628 
00629     //
00630     // Changed d_False into d_True in the following line to solve
00631     // Remedy 4778. MM 2001 03 08
00632     //
00633     if (event.getPersistent() != origEvt)
00634         scanEvent(BdbEventT( origEvt ), d_True);
00635 }
00636 
00637 int BdbLocateDb::scan( BdbAbsCollectionT<BdbEventT>* collection, 
00638                        d_Boolean trustMetaData,
00639                        d_Boolean updateMetaData )
00640 {
00641 #ifdef BDBSCANDB_TRACE
00642   cout << "Trying to scan (Tree) collection " << collection->name() << endl;
00643 #endif
00644   BdbHandle(BdbCollectionP) thePersColl = collection->persistent();
00645   if ( !BdbIsNull( thePersColl ) ) {
00646     checkItem( thePersColl );
00647     
00648     BdbMetaData theMetaData;
00649     collection->metaData( theMetaData );
00650     if ( ! theMetaData.isNull( )  )
00651       checkItem( theMetaData.persistent() ); // Check also the metadata, if any.
00652   }
00653   
00654   if ( collection->collections() > 0 ) {
00655     // This collection contains other collections. We assume it's 
00656     // a tree collection; thus, we recursively check each contained one.    
00657     BdbCollectionTCollTIterator collItr( *collection );
00658     BdbAbsCollectionT<BdbEventT>* embeddedColl = 0;
00659     while ( BdbcSuccess == collItr.next( embeddedColl ) ) {
00660         scan( embeddedColl, trustMetaData, updateMetaData );
00661     }
00662   } else {
00663     // There are no embedded collections. Assume it's a vector collection
00664     scanVectorCollection( collection, trustMetaData, updateMetaData );
00665   }
00666   return _dbs.size();
00667 }
00668 
00669 
00670 void
00671 BdbLocateDb::scanVectorCollection(  BdbAbsCollectionT<BdbEventT>* collection, 
00672                                     d_Boolean trustMetaData,
00673                                     d_Boolean updateMetaData )
00674 {
00675   assert( collection->collections() == 0 ); // See note below
00676   /*
00677    * NOTE: The previous assertion should _never_ fail. This is because this 
00678    * function is called from scanCollection, which is expected to check if
00679    * the collection is a vector collection or not. If this function fails,
00680    * perhaps there were changes in the implementation of event collections.
00681    * If so, please contact the pkg coordinator for BdbEventStore.
00682    */
00683 
00684   BdbStatus result = BdbcError;
00685 #ifdef BDBSCANDB_TRACE
00686   cout << "Trying to scan Vector collection " << collection->name() << endl;
00687 #endif
00688   if ( d_True == trustMetaData ) {
00689     result = useCollMetaData( collection );
00690   }
00691   
00692   if ( BdbcSuccess != result ) {
00693 #ifdef BDBSCANDB_TRACE
00694     cout << "Not using Metadata. Scanning..." << endl;
00695 #endif
00696     _theMgr.clear( );
00697     
00698     // Iterates over the events
00699     BdbCollectionTIterator<BdbEventT>* evtItr( collection->getIterator() );
00700     BdbEventT::ObjyRef nullRef;
00701     BdbEventT eventT(nullRef, d_True);
00702     while (BdbcSuccess == evtItr->next(eventT)) {
00703       scanEvent(eventT);
00704     }
00705     delete evtItr ;
00706     
00707     if ( d_True == updateMetaData ) {
00708       /*
00709        * Update the metadata info
00710        */
00711 #ifdef BDBSCANDB_TRACE
00712       cout << "I'm updating the MetaData..." << endl;
00713 #endif
00714       BdbMetaData meta;
00715       BdbMode oldMode = BdbEventStore::instance()->change( BdbcUpdate );
00716       assert( BdbcSuccess == collection->fetchMetaData( meta ) ); // See note below
00717       /*
00718        * NOTE: If the previous assertion fails, make sure that the 
00719        * transaction in which this function is called can be switched to 
00720        * update mode. This should be trivially enforced by the previous
00721        * line of code, so this assertion is not really supposed to fail.
00722        */
00723 
00724       _theMgr.setValidity( d_True );
00725       assert ( BdbcSuccess == _theMgr.end( meta ) ); // See note below
00726       /*      
00727        * NOTE: This operation is not supposed to fail. If it does, maybe the
00728        * end( ) method cannot acquire a write lock. Check for outstanding locks
00729        * on the federation.
00730        */
00731       BdbEventStore::instance()->change( oldMode, d_True );
00732     }
00733   }
00734 }
00735 
00736 /*
00737  * Try to access the collection's metadata. Return BdbcError if
00738  * metadata are non-existant or invalid.
00739  */
00740 BdbStatus 
00741 BdbLocateDb::useCollMetaData( BdbAbsCollectionT<BdbEventT>* collection )
00742 {
00743   BdbMetaData theMetaData;
00744   BdbStatus result = BdbcError;
00745 
00746   collection->metaData( theMetaData );
00747   BdbDistMetaDataMgr localMgr( theMetaData );
00748   if ( d_True == localMgr.valid( ) ) {
00749     // The metadata are valid. Use them
00750     vector<int> theDBList;
00751     localMgr.getDBList( theDBList );    
00752     for ( size_t i=0; i < theDBList.size( ); i++ ) {
00753       addDb( theDBList[i] );
00754     }
00755     result = BdbcSuccess;
00756   }
00757   return result;
00758 }
00759 
00760 // Fill the reference object with the reference of the next database
00761 //      and return true
00762 // Return false at the end of the list*/
00763 BdbStatus BdbLocateDb::next(BdbRef(BdbDBObj)& db)
00764 {
00765     BdbCollectRef* dbCR;
00766     if (_dbit!=_dbs.end()) {
00767       dbCR = *_dbit;
00768       db = dbCR->getDBRef();
00769       _dbit++;
00770       return BdbcSuccess;
00771     }
00772     
00773     // No more database in the list
00774     return BdbcError;
00775 }
00776 
00777 // Return the database id of the next invalid database
00778 // Return false at the end of the list
00779 BdbStatus BdbLocateDb::nextInvalid(int& dbid)
00780 {
00781     BdbCollectRef* dbCR;
00782     if (_invdbit!=InvRefs.end()) {
00783       dbCR=*_invdbit;
00784         dbid = (dbCR->getDBRef()).get_DB();
00785         _invdbit++;
00786         return BdbcSuccess;
00787     }
00788 
00789     // No more database in the list
00790     return BdbcError;
00791 }
00792 
00793 d_Boolean BdbLocateDb::isSelected(const BdbRef(BdbDBObj)& db) const
00794 {
00795     BdbCollectRef dbCR (db);
00796     return _dbs.find(&dbCR)!=_dbs.end();
00797 }
00798 
00799 // Fill the reference object with the reference of the next container
00800 //      and return true
00801 // Return false at the end of the list
00802 BdbStatus BdbLocateDb::nextContainer(BdbRef(BdbContObj)& cont)
00803 {
00804     BdbCollectRef* contCR;
00805     if(_contit!=_conts.end()) {
00806       contCR=*_contit;
00807       cont = contCR->getContRef();
00808       _contit++;
00809       return BdbcSuccess;
00810     }
00811 
00812     // No more database in the list
00813     return BdbcError;
00814 }
00815 
00816 d_Boolean BdbLocateDb::isSelected(const BdbRef(BdbContObj)& cont) const
00817 {
00818     BdbCollectRef contCR (cont);
00819     return _conts.find(&contCR)!=_conts.end();
00820 }

 


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

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