| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

DybDataSvc.cpp

Go to the documentation of this file.
00001 #define  DYBSVC_DYBDATASVC_CPP
00002 
00003 #include "GaudiKernel/DataObject.h"
00004 #include "GaudiKernel/GaudiException.h"
00005 #include "GaudiKernel/IConversionSvc.h"
00006 #include "GaudiKernel/IOpaqueAddress.h"
00007 #include "GaudiKernel/IRegistry.h"
00008 #include "GaudiKernel/ISvcLocator.h"
00009 #include "GaudiKernel/RegistryEntry.h"
00010 #include "GaudiKernel/SvcFactory.h"
00011 #include "GaudiKernel/MsgStream.h"
00012 
00013 #include "DataUtilities/DybArchiveList.h"
00014 #include "Event/RegistrationSequence.h"
00015 #include "DybDataSvc.h"
00016 
00017 // If you absolutely need optimization: switch off dynamic_cast.
00018 // This improves access to the data store roughly by 10 %
00019 // for balanced trees.
00020 //
00021 // M.Frank
00022 #define CAST_REGENTRY(x,y) dynamic_cast<x>(y)
00023 //#define CAST_REGENTRY(x,y) (x)(y)
00024 typedef DataSvcHelpers::RegistryEntry RegEntry;
00025 
00027 DybDataSvc::DybDataSvc(const std::string& name,
00028                        ISvcLocator* svc)
00029     : DataSvc(name,svc)
00030     , m_archiveSvc(0)
00031     , m_cnvSvc(0)
00032     , m_useAes(true)
00033 {
00034 
00035 
00036   declareProperty("RegSeqPath",
00037                   m_regSeqPath=RegistrationSequence::defaultLocation(),
00038                   "Path, in the TES, where the RegistrationSequnce object is kept");
00039   declareProperty("UseAes",m_useAes,
00040                   "Whether or not to use the AES, default is true");
00041   setProperty("ForceLeaves", "true");
00042 
00043   {
00044     MsgStream log(msgSvc(), "DybDataSvc::DybDataSvc()");
00045     log << MSG::DEBUG
00046         << "initializing"
00047         << endreq;
00048   }
00049 }
00050 
00052 DybDataSvc::~DybDataSvc()
00053 {
00054   if (0 != m_archiveSvc) {
00055     m_archiveSvc->release();
00056   }
00057 
00058   if (0 != m_cnvSvc) {
00059     m_cnvSvc->release();
00060   }
00061 }
00062 
00064 StatusCode DybDataSvc::initialize()
00065 {
00066   StatusCode status  = DataSvc::initialize();
00067   if (status.isFailure()) {
00068     throw GaudiException("Could not initialize super class",
00069                          name(),
00070                          status);
00071   }
00072 
00073   MsgStream log(msgSvc(), "DybDataSvc::initialize()");
00074   log << MSG::DEBUG << "initializing DybDataSvc @"
00075       << (void*)this
00076       << " named " << name()
00077       << " UseAes is " << m_useAes
00078       << " ForceLeaves is " << m_forceLeaves
00079       << endreq;
00080 
00081   ISvcLocator*    svc_loc = serviceLocator();
00082 
00083   status = svc_loc->service("EventPersistencySvc",
00084                             m_cnvSvc,
00085                             true);
00086   if( status.isFailure() ) {
00087     throw GaudiException("Service [EventPersistencySvc] not found",
00088                          name(),
00089                          status);
00090   }
00091   status = setDataLoader( m_cnvSvc );
00092   if( status.isFailure() ) {
00093     throw GaudiException("Could not set DataLoader",
00094                          name(),
00095                          status);
00096   }
00097 
00098   log << MSG::DEBUG << "DybDataSvc @" << (void*)this
00099       << " has UseAes = " << m_useAes << endreq;
00100 
00101   if (m_useAes) {
00102     log << MSG::INFO
00103         << "Using [EvtDataSvc] as the archive service"
00104         << endreq;
00105 
00106     status = svc_loc->service("EventDataArchiveSvc", m_archiveSvc, true);
00107     if( status.isFailure() || !m_archiveSvc ) {
00108       log << MSG::ERROR << "Service [EventDataArchiveSvc] not found" << endreq;
00109       return status;
00110     }
00111     SmartIF<IProperty> property(m_archiveSvc);
00112     if (!property) {
00113       log << MSG::ERROR
00114           << "The EvtDataSvc has no property interface" << endreq;
00115       return StatusCode::FAILURE;
00116     }
00117     property->setProperty("ForceLeaves","true");
00118   }
00119   else {
00120     log << MSG::DEBUG
00121         << "DybDataSvc @"
00122         << (void*)this
00123         << ", not using Archive Event Store (AES)"
00124         << endreq;
00125   }
00126   return status;
00127 }
00128 
00130 StatusCode DybDataSvc::reinitialize()
00131 {
00132   // Do nothing for this service
00133   return StatusCode::SUCCESS;
00134 }
00135 
00137 StatusCode DybDataSvc::finalize()
00138 {
00139   if( 0 != m_archiveSvc ) {
00140     m_archiveSvc->release();
00141   }
00142   m_archiveSvc = 0;
00143 
00144   if( 0 != m_cnvSvc ) {
00145     m_cnvSvc->release();
00146   }
00147   m_cnvSvc = 0;
00148 
00149   DataSvc::finalize().ignore();
00150   return StatusCode::SUCCESS ;
00151 }
00152 
00154 IDataProviderSvc* DybDataSvc::archiveSvc() const
00155 {
00156   return m_archiveSvc;
00157 }
00158 
00159 // Override 'setRoot' to also set the root of the Archive if not
00160 // already set.
00161 StatusCode DybDataSvc::setRoot(const std::string& root_path,
00162                                DataObject* pRootObj) {
00163   StatusCode result = DataSvc::setRoot(root_path,
00164                                        pRootObj);
00165   if (m_useAes) {
00166     DataObject* existingRoot = 0;
00167     archiveSvc()->retrieveObject(root_path,
00168                                  existingRoot).ignore();
00169     if ( 0 == existingRoot ) {
00170       IDataManagerSvc* archiveMgr = dynamic_cast<IDataManagerSvc*>(archiveSvc());
00171       StatusCode status = archiveMgr->setRoot(root_path,
00172                                               new DybArchiveList());
00173       if (status.isFailure()) return status;
00174     }
00175   }
00176   return result;
00177 }
00178 
00179 // Override 'setRoot' to also set the root of the Archive if not
00180 // already set.
00181 StatusCode DybDataSvc::setRoot(const std::string& root_path,
00182                                IOpaqueAddress* pRootAddr) {
00183   StatusCode result = DataSvc::setRoot(root_path,
00184                                        pRootAddr);
00185   if (m_useAes) {
00186     DataObject* existingRoot = 0;
00187     archiveSvc()->retrieveObject(root_path,
00188                                  existingRoot).ignore();
00189     if ( 0 == existingRoot ) {
00190       IDataManagerSvc* archiveMgr = dynamic_cast<IDataManagerSvc*>(archiveSvc());
00191       StatusCode status = archiveMgr->setRoot(root_path,
00192                                               new DybArchiveList());
00193       if (status.isFailure()) return status;
00194     }
00195   }
00196   return result;
00197 }
00198 
00200 StatusCode DybDataSvc::loadObject(IConversionSvc* pLoader,
00201                                   IRegistry* pRegistry) {
00202 
00203   {
00204     MsgStream log(msgSvc(), "DybDataSvc::loadObject()");
00205     log << MSG::DEBUG
00206         << "loading "<<pRegistry->identifier()
00207         << " with loader "<<pLoader
00208         << endreq;
00209   }
00210   
00211   StatusCode result = DataSvc::loadObject(pLoader,
00212                                           pRegistry);
00213 
00215   RegEntry *pEntry = CAST_REGENTRY(RegEntry*,pRegistry);
00216   DataObject* pObject = pEntry->object();
00217 
00218   if (0 == pObject) {
00219     return result;
00220   }
00221 
00222   {
00223     MsgStream log(msgSvc(), "DybDataSvc::loadObject()");
00224     log << MSG::DEBUG
00225         << " registry->identifier() == " << pRegistry->identifier()
00226         << " pObject->registry()->identifier() == " << pObject->registry()->identifier()
00227         << endreq;
00228   }
00229 
00230   result = sequenceObject(pObject);
00231   if (result.isFailure()) return result;
00232 
00233   if (m_useAes) {
00234     result = archiveObject(pObject);
00235   }
00236   return result;
00237 }
00238 
00240 StatusCode DybDataSvc::registerAddress(IRegistry* parentObj,
00241                                        const std::string& objPath,
00242                                        IOpaqueAddress* pAddress)
00243 {
00244   MsgStream log(msgSvc(), "DybDataSvc::registerAddress()");
00245 
00246   StatusCode result = DataSvc::registerAddress(parentObj,
00247                                                objPath,
00248                                                pAddress);
00249   if (result.isFailure()) {
00250       return result;
00251   }
00252 
00253   // Do nothing more if there is no parent object (as this will be
00254   // handled later by the recursion).
00255   if (0 == parentObj ) {
00256     return result;
00257   }
00258 
00259   // Do nothing more if the object path contains a separator (as this
00260   // will be handled later by the recursion).
00261   std::string::size_type sep = objPath.find(SEPARATOR,1);
00262   if ( sep != std::string::npos ) {
00263     return result;
00264   }
00265 
00266   // Get the full path of the registered object.
00267   if (0 == pAddress) {
00268     return result;
00269   }
00270 
00271   IRegistry* entry = pAddress->registry();
00272   if (0 == entry) {
00273     return result;
00274   }
00275 
00276   if (m_useAes) {
00277     // Retrieve collection
00278     DataObject* collection=0;
00279     archiveSvc()->retrieveObject(entry->identifier(),
00280                                  collection).ignore();
00281 
00282     if (0 == collection) {
00283       StatusCode status = archiveSvc()->registerObject(entry->identifier(),
00284                                                        new DybArchiveList());
00285       if (status.isFailure()) return status;
00286     }
00287   }
00288 
00290 
00291   return StatusCode::SUCCESS;
00292 }
00293 
00295 StatusCode DybDataSvc::registerObject(DataObject* parentObj,
00296                                       const std::string& objPath,
00297                                       DataObject* pObject)
00298 {
00299   MsgStream log(msgSvc(), "DybDataSvc::registerObject()");
00300   log << MSG::DEBUG
00301       << "use aes = " << m_useAes << " "
00302       << "parent = \"" << (parentObj ? parentObj->name() : "(none)")  << "\" "
00303       << "path = \"" << objPath << "\" "
00304       << "obj = \"" << (pObject ? pObject->name() : "(none)") << "\""
00305       << endreq;
00306 
00307   // wangzhe
00308   // The following part makes sure put() method can deal with TES, AES
00309   // smoothly. User will not worry about AES usage and unregisterObject again.
00310   // When the second header object comes into TES, the existing object in that 
00311   // path will be unregistered.
00312   // By doing this the last data object produced is always in TES.
00313   // When the event rate is low the data in TES in top stage using in Fifteen
00314   // is the same as push method
00315   if(m_useAes) {
00316     // This story is not about usual data object.
00317     if( pObject->clID() != DataObject::classID() ) {
00318       // If choose to use AES, firstly check whether that path exists 
00319       // and whether there are data object with it.
00320       // Because some data object might already be there.
00321       // If it really exists unregister it since it is in AES now.
00322       // It is safe to remove it from TES.
00323       DataObject* pEstObj=0;
00324       StatusCode sc = DataSvc::findObject(parentObj,objPath,pEstObj);
00325       if(sc.isSuccess()) {
00326         if(pEstObj!=0) {
00327           DataSvc::unregisterObject(pEstObj);
00328           // Why there is a release? See DocDB 3242, page 2 memo
00329           // Gaudi isn't perfect and has defect.
00330           pEstObj->release();
00331         }
00332       }
00333     }
00334   } else {
00335     // If AES is not chosen to use, then ignore this step.
00336     // For the case of only using TES, such an operation will possibly remove that
00337     // object from memory if there is no other place holding it.
00338     // From this point of view it is dangerous to unregister an object like this.
00339     // If user really want to register two objects in the same path,
00340     // it is strongly encouraged that he/she should do it by themselves.
00341   }
00342   // wz
00343 
00344   StatusCode result = DataSvc::registerObject(parentObj,
00345                                               objPath,
00346                                               pObject);
00347 
00348   // Do nothing more if there is no parent object (as this will be
00349   // handled later by the recursion).
00350   if (0 == parentObj ) {
00351     return result;
00352   }
00353 
00354   // Do nothing more if the object path contains a separator (as this
00355   // will be handled later by the recursion).
00356   std::string::size_type sep = objPath.find(SEPARATOR,1);
00357   if ( sep != std::string::npos ) {
00358     return result;
00359   }
00360 
00361   // Get the full path of the registered object.
00362   if (0 == pObject) {
00363     return result;
00364   }
00365 
00366   IRegistry* pRegistry = pObject->registry();
00367   if (0 == pRegistry) {
00368     return result;
00369   }
00370 
00371   result = sequenceObject(pObject);
00372   if (result.isFailure()) return result;
00373 
00374   if (m_useAes) {
00375     result = archiveObject(pObject);
00376   }
00377   return result;
00378 }
00379 
00380 StatusCode DybDataSvc::archiveObject(DataObject* pObject) {
00381 
00382   std::string path = pObject->registry()->identifier();
00383 
00384   MsgStream log(msgSvc(), "DybDataSvc::archiveObject()");
00385 
00386   if (!m_useAes) {
00387     log << MSG::ERROR << "archiveObject() called but told not to use AES"
00388         << endreq;
00389     return StatusCode::FAILURE;
00390   }
00391 
00392   if (pObject->clID() == DataObject::classID()) {
00393       log << MSG::DEBUG
00394           << "Not archiving plain DataObject at "
00395           << path << endreq;
00396       return StatusCode::SUCCESS;
00397   }
00398 
00399   // Retrieve collection and add object.
00400   DataObject* collection=0;
00401   StatusCode sc =  archiveSvc()->retrieveObject(path, collection);
00402   sc.ignore();
00403   //if (sc.isFailure()) {
00404   //    log << MSG::WARNING << "failed to retrieve list at "
00405   //        << pRegistry->identifier()
00406   //        << " will register new one" << endreq;
00407   //}
00408 
00409   DybArchiveList* list = 0;
00410   if (0 == collection) {
00411     list = new DybArchiveList();
00412     StatusCode status = archiveSvc()->registerObject(path, list);
00413     if (!status.isSuccess()) {
00414       log << MSG::WARNING << "failed to register list at "
00415           << path << endreq;
00416       return StatusCode(status.getCode(),
00417                         status.severity());
00418     }
00419   } else {
00420     list = dynamic_cast<DybArchiveList*>(collection);
00421   }
00422 
00423   list->push_front((DybArchiveList::const_reference)pObject);
00424 
00425   return StatusCode::SUCCESS;
00426 }
00427 
00428 StatusCode DybDataSvc::sequenceObject(DataObject* pObject)
00429 {
00430   // Record registration sequence of this object.
00431 
00432   // Don't sequence base DataObject, they just make up directory structure.
00433   if (pObject->clID() == CLID_DataObject) return StatusCode::SUCCESS;
00434 
00435   MsgStream log(msgSvc(), "DybDataSvc::sequenceObject()");
00436 
00437   std::string path = pObject->registry()->identifier();
00438 
00439   // Do not sequence the RegistrationSequnce to avoid infinite loop
00440   if (m_regSeqPath.value() == path) {
00441     return StatusCode::SUCCESS;
00442   }
00443 
00444   {
00445       DataObject* dobj = 0;
00446       StatusCode sc = retrieveObject("/Event",dobj);
00447       if (sc.isFailure()) {
00448           log << MSG::ERROR << "falied to retrieve /Event" << endreq;
00449           return sc;
00450       }
00451       else {
00452           //log << MSG::INFO << "got /Event" << endreq;
00453       }
00454   }
00455 
00456   // Retieve registration sequence object.
00457   DataObject* object = 0;
00458   StatusCode sc = retrieveObject(m_regSeqPath.value(),object);
00459   sc.ignore();
00460   //if (sc.isFailure()) {
00461   //    log << MSG::WARNING << "failed to retrieve reg seq obj from "
00462   //        << m_regSeqPath.value() << " will register new one " << endreq;
00463   //}
00464   RegistrationSequence* regSeq = 0;
00465   if (0 == object) {
00466     regSeq = new RegistrationSequence();
00467     StatusCode status = registerObject(0,m_regSeqPath.value(),regSeq);
00468     if (!status.isSuccess()) {
00469       log << MSG::WARNING << "failed to register object "
00470           << m_regSeqPath.value() << endreq;
00471 
00472       return StatusCode(status.getCode(),
00473                         status.severity());
00474     }
00475   } else {
00476     regSeq = dynamic_cast<RegistrationSequence*>(object);
00477   }
00478   log << MSG::DEBUG << "inserting into RegSeq: " << path << endreq;
00479 
00480   regSeq->insert(pObject->registry(), pObject, true);
00481 
00482   return StatusCode::SUCCESS;
00483 }
00484 
00485 // Local Variables:
00486 // c-basic-offset: 2
00487 // End:
00488 
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:40:07 2011 for DybEventMgr by doxygen 1.4.7