| # Gaudi Framework, version v20r2
Generated: 18 Jul 2008

- Main Page
- Namespaces
- Classes
- Files
- Directories
- Related Pages

- Search for |

- File List
- File Members

# RegistryEntry.cpp

Go to the documentation of this file.

    00001 // $Header: /local/reps/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     const char* data = path.data();
    00263     for (Store::const_iterator i = m_store.begin(); i != m_store.end(); i++ )   {
    00264       RegistryEntry* regEnt = CAST_REGENTRY(RegistryEntry*, *i);
    00265       const std::string& nam = regEnt->name();
    00266       if ( nam.length() == len2 )   {
    00267         if ( std::equal(nam.begin(), nam.begin()+len2, data)  )    {
    00268           try   {
    00269             if ( loc1 != std::string::npos )   {
    00270               std::string search_path(path, loc1, len);
    00271               IRegistry* pDir = regEnt->find(search_path);
    00272               if ( 0 != pDir )    {
    00273                 return CAST_REGENTRY(RegistryEntry*, pDir);
    00274               }
    00275               return 0;
    00276             }
    00277             else  {
    00278               return CAST_REGENTRY(RegistryEntry*, *i);
    00279             }
    00280           }
    00281           catch (...)   {
    00282           }
    00283         }
    00284       }
    00285     }
    00286     if ( m_path.length() == len2 )    {
    00287       if ( std::equal(m_path.begin(), m_path.begin()+len2, data)  )    {
    00288         if (len2 < len)   {
    00289           std::string search_path(path, loc1, len);
    00290           return i_find(search_path);
    00291         }
    00292         //return this;
    00293       }
    00294     }
    00295   }
    00296   return 0;
    00297 }
    00298
    00300 DataSvcHelpers::RegistryEntry* DataSvcHelpers::RegistryEntry::i_find(const DataObject* key)  const  {
    00301   if ( 0 != key )  {
    00302     if ( key == m_pObject )    {
    00303       return const_cast<RegistryEntry*>(this);
    00304     }
    00305     // Look in the immediate level:
    00306     RegistryEntry *result = CAST_REGENTRY(RegistryEntry*, i_find(key->registry()));
    00307     if ( 0 != result ) return result;
    00308     // Go levels down
    00309     for (Store::const_iterator i = m_store.begin(); i != m_store.end(); i++ )   {
    00310       try   {
    00311         const RegistryEntry *entry = CAST_REGENTRY(RegistryEntry*, *i);
    00312         if( 0 != (result = entry->i_find(key)) )
    00313           return result;
    00314       }
    00315       catch ( ... )   {    }
    00316     }
    00317   }
    00318   return 0;
    00319 }
    00320
    00321 // Traverse registry tree
    00322 long DataSvcHelpers::RegistryEntry::traverseTree(IDataStoreAgent* pAgent, int level)    {
    00323   bool go_down = pAgent->analyse(this, level);
    00324   long status = StatusCode::SUCCESS;
    00325   if ( go_down )    {
    00326     for ( Store::iterator i = m_store.begin(); i != m_store.end(); i++ )   {
    00327       try   {
    00328         RegistryEntry* entry = CAST_REGENTRY(RegistryEntry*, *i);
    00329         entry->traverseTree(pAgent, level+1);
    00330       }
    00331       catch (...)   {
    00332         status = StatusCode::FAILURE;
    00333       }
    00334     }
    00335   }
    00336   return status;
    00337 }
    00338
    00339 // Recursive helper to assemble the full path name of the entry
    00340 void DataSvcHelpers::RegistryEntry::assemblePath(std::string& buffer)  const  {
    00341   if ( m_pParent != 0 )    {
    00342     m_pParent->assemblePath(buffer);
    00343   }
    00344   buffer += m_path;
    00345 }