Gaudi Framework, version v22r2

Home   Generated: Tue May 10 2011

RegistryEntry.cpp

Go to the documentation of this file.
00001 // $Header: /tmp/svngaudi/tmp.jEpFh25751/Gaudi/GaudiKernel/src/Lib/RegistryEntry.cpp,v 1.12 2006/07/07 13:15:30 hmd Exp $
00002 //====================================================================
00003 //      RegistryEntry.cpp
00004 //--------------------------------------------------------------------
00005 //
00006 //      Package    : DataSvc ( The LHCb Offline System)
00007 //
00008 //  Description: implementation of the Transient data store
00009 //
00010 //      Author     : M.Frank
00011 //  History    :
00012 // +---------+----------------------------------------------+---------
00013 // |    Date |                 Comment                      | Who
00014 // +---------+----------------------------------------------+---------
00015 // | 29/10/98| Initial version                              | MF
00016 // | 03/02/99| Protect dynamic_cast with try-catch clauses  | MF
00017 // +---------+----------------------------------------------+---------
00018 //
00019 //====================================================================
00020 #define  DATASVC_REGISTRYENTRY_CPP
00021 
00022 // STL include files
00023 #include <algorithm>
00024 
00025 // Interfaces
00026 #include "GaudiKernel/IDataStoreAgent.h"
00027 #include "GaudiKernel/IOpaqueAddress.h"
00028 
00029 // Framework include files
00030 #include "GaudiKernel/DataObject.h"
00031 #include "GaudiKernel/RegistryEntry.h"
00032 
00033 
00034 // If you absolutely need optimization: switch off dynamic_cast.
00035 // This improves access to the data store roughly by more than 10 %
00036 // for balanced trees.
00037 //
00038 // M.Frank
00039 //
00040 #define CAST_REGENTRY(x,y) dynamic_cast<x>(y)
00041 //#define CAST_REGENTRY(x,y) (x)(y)
00042 enum Seperator { SEPARATOR='/' };
00043 
00045 DataSvcHelpers::RegistryEntry::RegistryEntry(const std::string& path, RegistryEntry* parent)
00046 : m_refCount(0),
00047   m_isSoft(false),
00048   m_path(path),
00049   m_pParent(parent),
00050   m_pAddress(0),
00051   m_pObject(0),
00052   m_pDataProviderSvc(0)
00053 {
00054   std::string::size_type sep = m_path.rfind(SEPARATOR);
00055   if ( path[0] != SEPARATOR )   {
00056     m_path.insert(m_path.begin(), SEPARATOR);
00057   }
00058   if ( sep != std::string::npos )    {
00059     m_path.erase(0,sep);
00060   }
00061   assemblePath(m_fullpath);
00062   addRef();
00063 }
00064 
00066 DataSvcHelpers::RegistryEntry::~RegistryEntry()  {
00067   deleteElements();
00068   if ( 0 != m_pObject  )   {
00069     if ( !m_isSoft ) m_pObject->setRegistry(0);
00070     m_pObject->release();
00071   }
00072   if ( 0 != m_pAddress )   {
00073     if ( !m_isSoft ) m_pAddress->setRegistry(0);
00074     m_pAddress->release();
00075   }
00076 }
00077 
00079 unsigned long DataSvcHelpers::RegistryEntry::release()  {
00080   unsigned long cnt = --m_refCount;
00081   if ( 0 == m_refCount )   {
00082     delete this;
00083   }
00084   return cnt;
00085 }
00086 
00088 void DataSvcHelpers::RegistryEntry::setParent(RegistryEntry* pParent)    {
00089   m_pParent = pParent;
00090   m_fullpath = "";
00091   assemblePath(m_fullpath);
00092 }
00093 
00095 void DataSvcHelpers::RegistryEntry::makeSoft(DataObject* pObject)   {
00096   m_isSoft = true;
00097   setObject(pObject);
00098 //  if ( 0 != m_pObject )   { // Useless: This justs sets my own address again...
00099 //    setAddress(m_pObject->address());
00100 //  }
00101 }
00102 
00104 void DataSvcHelpers::RegistryEntry::makeSoft(IOpaqueAddress* pAddress)   {
00105   m_isSoft = true;
00106   setAddress(pAddress);
00107 }
00108 
00110 void DataSvcHelpers::RegistryEntry::makeHard(DataObject* pObject)   {
00111   makeSoft(pObject);
00112   m_isSoft = false;
00113   if ( 0 != m_pObject )   {
00114     m_pObject->setRegistry(this);
00115   }
00116   if ( 0 != m_pAddress )   {
00117     m_pAddress->setRegistry(this);
00118   }
00119 }
00120 
00122 void DataSvcHelpers::RegistryEntry::makeHard(IOpaqueAddress* pAddress)   {
00123   m_isSoft = false;
00124   setAddress(pAddress);
00125 }
00126 
00128 void DataSvcHelpers::RegistryEntry::setAddress( IOpaqueAddress* pAddress )    {
00129   if ( 0 != pAddress  )   {
00130     pAddress->addRef();
00131     pAddress->setRegistry(this);
00132   }
00133   if ( 0 != m_pAddress ) m_pAddress->release();
00134   m_pAddress = pAddress;
00135 }
00136 
00138 void DataSvcHelpers::RegistryEntry::setObject( DataObject* pObject )   {
00139   if ( 0 != pObject  )  {
00140     pObject->addRef();
00141     if ( !isSoft() ) pObject->setRegistry(this);
00142   }
00143   if ( 0 != m_pObject ) m_pObject->release();
00144   m_pObject = pObject;
00145 }
00146 
00148 long DataSvcHelpers::RegistryEntry::remove  ( IRegistry* obj )    {
00149   try   {
00150     RegistryEntry* pEntry = dynamic_cast<RegistryEntry*>(obj);
00151     Store::iterator i = std::remove(m_store.begin(), m_store.end(), pEntry);
00152     if (i != m_store.end())   {
00153       pEntry->release();
00154       m_store.erase( i, m_store.end() );
00155     }
00156   }
00157   catch ( ... )   {     }
00158   return m_store.size();
00159 }
00160 
00162 long DataSvcHelpers::RegistryEntry::remove ( const std::string& nam )  {
00163   if ( nam[0] != SEPARATOR )   {
00164     std::string path = nam;
00165     path.insert(path.begin(), SEPARATOR);
00166     return remove(path);
00167   }
00168   // if this object is already present, this is an error....
00169   for (Store::iterator i = m_store.begin(); i != m_store.end(); i++ )   {
00170     if ( nam == (*i)->name() )   {
00171       remove(*i);
00172       return StatusCode::SUCCESS;
00173     }
00174   }
00175   return StatusCode::FAILURE;
00176 }
00177 
00179 DataSvcHelpers::RegistryEntry* DataSvcHelpers::RegistryEntry::i_add(const std::string& nam)    {
00180   if ( nam[0] != SEPARATOR )   {
00181     std::string path = nam;
00182     path.insert(path.begin(), SEPARATOR);
00183     return i_add(path);
00184   }
00185   // if this object is already present, this is an error....
00186   for (Store::iterator i = m_store.begin(); i != m_store.end(); i++ )   {
00187     if ( nam == (*i)->name() )  {
00188       return 0;
00189     }
00190   }
00191   return new RegistryEntry( nam, this );
00192 }
00193 
00195 long DataSvcHelpers::RegistryEntry::add( IRegistry* obj )    {
00196   try   {
00197     RegistryEntry* pEntry = CAST_REGENTRY(RegistryEntry*, obj);
00198     pEntry->setDataSvc(m_pDataProviderSvc);
00199     m_store.push_back(pEntry);
00200     pEntry->setParent(this);
00201     if ( !pEntry->isSoft() && pEntry->address() != 0 )   {
00202       pEntry->address()->setRegistry(pEntry);
00203     }
00204   }
00205   catch ( ... )   {
00206   }
00207   return m_store.size();
00208 }
00209 
00211 long DataSvcHelpers::RegistryEntry::add ( const std::string& name, DataObject* pObject, bool is_soft )  {
00212   RegistryEntry* entry = i_add(name);
00213   if ( 0 != entry )   {
00214     ( is_soft ) ? entry->makeSoft(pObject) : entry->makeHard(pObject);
00215     add( entry );
00216     return StatusCode::SUCCESS;
00217   }
00218   return StatusCode::FAILURE;
00219 }
00220 
00222 long DataSvcHelpers::RegistryEntry::add ( const std::string& name, IOpaqueAddress* pAddress, bool is_soft )  {
00223   RegistryEntry* entry = i_add(name);
00224   if ( 0 != entry )   {
00225     ( is_soft ) ? entry->makeSoft(pAddress) : entry->makeHard(pAddress);
00226     add( entry );
00227     return StatusCode::SUCCESS;
00228   }
00229   return StatusCode::FAILURE;
00230 }
00231 
00233 long DataSvcHelpers::RegistryEntry::deleteElements()   {
00234   for (Store::iterator i = m_store.begin(); i != m_store.end(); i++ )   {
00235     RegistryEntry* entry = CAST_REGENTRY(RegistryEntry*, *i);
00236     if ( 0 != entry )   {
00237       entry->deleteElements();
00238       entry->release();
00239     }
00240   }
00241   m_store.erase(m_store.begin(), m_store.end());
00242   return 0;
00243 }
00244 
00246 IRegistry* DataSvcHelpers::RegistryEntry::i_find( const IRegistry* obj )  const  {
00247   Store::const_iterator i = std::find(m_store.begin(),m_store.end(),obj);
00248   return (i==m_store.end()) ? 0 : (*i);
00249 }
00250 
00252 DataSvcHelpers::RegistryEntry* DataSvcHelpers::RegistryEntry::i_find(const std::string& path)   const    {
00253   if ( path[0] != SEPARATOR )    {
00254     std::string thePath = path;
00255     thePath.insert(thePath.begin(), SEPARATOR);
00256     return i_find(thePath);
00257   }
00258   else  {
00259     std::string::size_type len  = path.length();
00260     std::string::size_type loc1 = path.find(SEPARATOR,1);
00261     std::string::size_type len2 = loc1 != std::string::npos ? loc1 : len;
00262     for (Store::const_iterator i = m_store.begin(); i != m_store.end(); i++ )   {
00263       RegistryEntry* regEnt = CAST_REGENTRY(RegistryEntry*, *i);
00264       const std::string& nam = regEnt->name();
00265       // check that the first len2 chars of path are the same as nam
00266       // (i.e. match {len2:3 nam:"/Ab" path:"/Ab/C"}
00267       // but not {len2:3 nam:"/Abc" path:"/Ab/C"})
00268       if ( path.compare(0, len2, nam) == 0 ) {
00269         try {
00270           if ( loc1 != std::string::npos ) {
00271             std::string search_path(path, loc1, len);
00272             IRegistry* pDir = regEnt->find(search_path);
00273             if ( 0 != pDir )    {
00274               return CAST_REGENTRY(RegistryEntry*, pDir);
00275             }
00276             return 0;
00277           }
00278           else  {
00279             return CAST_REGENTRY(RegistryEntry*, *i);
00280           }
00281         }
00282         catch (...)   {
00283         }
00284       }
00285     }
00286     // If this node is "/NodeA", this part allows to find "/NodeA/NodeB" as
00287     // our "/NodeB" child.
00288     if ( path.compare(0, len2, m_path) == 0 ) {
00289       if (len2 < len)   {
00290         std::string search_path(path, loc1, len);
00291         return i_find(search_path);
00292       }
00293     }
00294   }
00295   return 0;
00296 }
00297 
00299 DataSvcHelpers::RegistryEntry* DataSvcHelpers::RegistryEntry::i_find(const DataObject* key)  const  {
00300   if ( 0 != key )  {
00301     if ( key == m_pObject )    {
00302       return const_cast<RegistryEntry*>(this);
00303     }
00304     // Look in the immediate level:
00305     RegistryEntry *result = CAST_REGENTRY(RegistryEntry*, i_find(key->registry()));
00306     if ( 0 != result ) return result;
00307     // Go levels down
00308     for (Store::const_iterator i = m_store.begin(); i != m_store.end(); i++ )   {
00309       try   {
00310         const RegistryEntry *entry = CAST_REGENTRY(RegistryEntry*, *i);
00311         if( 0 != (result = entry->i_find(key)) )
00312           return result;
00313       }
00314       catch ( ... )   {    }
00315     }
00316   }
00317   return 0;
00318 }
00319 
00320 // Traverse registry tree
00321 long DataSvcHelpers::RegistryEntry::traverseTree(IDataStoreAgent* pAgent, int level)    {
00322   bool go_down = pAgent->analyse(this, level);
00323   long status = StatusCode::SUCCESS;
00324   if ( go_down )    {
00325     for ( Store::iterator i = m_store.begin(); i != m_store.end(); i++ )   {
00326       try   {
00327         RegistryEntry* entry = CAST_REGENTRY(RegistryEntry*, *i);
00328         entry->traverseTree(pAgent, level+1);
00329       }
00330       catch (...)   {
00331         status = StatusCode::FAILURE;
00332       }
00333     }
00334   }
00335   return status;
00336 }
00337 
00338 // Recursive helper to assemble the full path name of the entry
00339 void DataSvcHelpers::RegistryEntry::assemblePath(std::string& buffer)  const  {
00340   if ( m_pParent != 0 )    {
00341     m_pParent->assemblePath(buffer);
00342   }
00343   buffer += m_path;
00344 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Tue May 10 2011 18:53:46 for Gaudi Framework, version v22r2 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004