![]() |
|
|
Generated: 24 Nov 2008 |
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 }