| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

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

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
RegistryEntry.cpp
Go to the documentation of this file.
1 // $Header: /tmp/svngaudi/tmp.jEpFh25751/Gaudi/GaudiKernel/src/Lib/RegistryEntry.cpp,v 1.12 2006/07/07 13:15:30 hmd Exp $
2 //====================================================================
3 // RegistryEntry.cpp
4 //--------------------------------------------------------------------
5 //
6 // Package : DataSvc ( The LHCb Offline System)
7 //
8 // Description: implementation of the Transient data store
9 //
10 // Author : M.Frank
11 // History :
12 // +---------+----------------------------------------------+---------
13 // | Date | Comment | Who
14 // +---------+----------------------------------------------+---------
15 // | 29/10/98| Initial version | MF
16 // | 03/02/99| Protect dynamic_cast with try-catch clauses | MF
17 // +---------+----------------------------------------------+---------
18 //
19 //====================================================================
20 #define DATASVC_REGISTRYENTRY_CPP
21
22 // STL include files
23 #include <algorithm>
24
25 // Interfaces
26 #include "GaudiKernel/IDataStoreAgent.h"
27 #include "GaudiKernel/IOpaqueAddress.h"
28
29 // Framework include files
30 #include "GaudiKernel/DataObject.h"
31 #include "GaudiKernel/RegistryEntry.h"
32
33
34 // If you absolutely need optimization: switch off dynamic_cast.
35 // This improves access to the data store roughly by more than 10 %
36 // for balanced trees.
37 //
38 // M.Frank
39 //
40 #define CAST_REGENTRY(x,y) dynamic_cast<x>(y)
41 //#define CAST_REGENTRY(x,y) (x)(y)
42 enum Seperator { SEPARATOR='/' };
43
45 DataSvcHelpers::RegistryEntry::RegistryEntry(const std::string& path, RegistryEntry* parent)
46 : m_refCount(0),
47 m_isSoft(false),
48 m_path(path),
49 m_pParent(parent),
50 m_pAddress(0),
51 m_pObject(0),
52 m_pDataProviderSvc(0)
53 {
54 std::string::size_type sep = m_path.rfind(SEPARATOR);
55 if ( path[0] != SEPARATOR ) {
56 m_path.insert(m_path.begin(), SEPARATOR);
57 }
58 if ( sep != std::string::npos ) {
59 m_path.erase(0,sep);
60 }
61 assemblePath(m_fullpath);
62 addRef();
63 }
64
66 DataSvcHelpers::RegistryEntry::~RegistryEntry() {
67 deleteElements();
68 if ( 0 != m_pObject ) {
69 if ( !m_isSoft ) m_pObject->setRegistry(0);
70 m_pObject->release();
71 }
72 if ( 0 != m_pAddress ) {
73 if ( !m_isSoft ) m_pAddress->setRegistry(0);
74 m_pAddress->release();
75 }
76 }
77
79 unsigned long DataSvcHelpers::RegistryEntry::release() {
80 unsigned long cnt = --m_refCount;
81 if ( 0 == m_refCount ) {
82 delete this;
83 }
84 return cnt;
85 }
86
88 void DataSvcHelpers::RegistryEntry::setParent(RegistryEntry* pParent) {
89 m_pParent = pParent;
90 m_fullpath = "";
91 assemblePath(m_fullpath);
92 }
93
95 void DataSvcHelpers::RegistryEntry::makeSoft(DataObject* pObject) {
96 m_isSoft = true;
97 setObject(pObject);
98 // if ( 0 != m_pObject ) { // Useless: This justs sets my own address again...
99 // setAddress(m_pObject->address());
100 // }
101 }
102
104 void DataSvcHelpers::RegistryEntry::makeSoft(IOpaqueAddress* pAddress) {
105 m_isSoft = true;
106 setAddress(pAddress);
107 }
108
110 void DataSvcHelpers::RegistryEntry::makeHard(DataObject* pObject) {
111 makeSoft(pObject);
112 m_isSoft = false;
113 if ( 0 != m_pObject ) {
114 m_pObject->setRegistry(this);
115 }
116 if ( 0 != m_pAddress ) {
117 m_pAddress->setRegistry(this);
118 }
119 }
120
122 void DataSvcHelpers::RegistryEntry::makeHard(IOpaqueAddress* pAddress) {
123 m_isSoft = false;
124 setAddress(pAddress);
125 }
126
128 void DataSvcHelpers::RegistryEntry::setAddress( IOpaqueAddress* pAddress ) {
129 if ( 0 != pAddress ) {
130 pAddress->addRef();
131 pAddress->setRegistry(this);
132 }
133 if ( 0 != m_pAddress ) m_pAddress->release();
134 m_pAddress = pAddress;
135 }
136
138 void DataSvcHelpers::RegistryEntry::setObject( DataObject* pObject ) {
139 if ( 0 != pObject ) {
140 pObject->addRef();
141 if ( !isSoft() ) pObject->setRegistry(this);
142 }
143 if ( 0 != m_pObject ) m_pObject->release();
144 m_pObject = pObject;
145 }
146
148 long DataSvcHelpers::RegistryEntry::remove ( IRegistry* obj ) {
149 try {
150 RegistryEntry* pEntry = dynamic_cast<RegistryEntry*>(obj);
151 Store::iterator i = std::remove(m_store.begin(), m_store.end(), pEntry);
152 if (i != m_store.end()) {
153 pEntry->release();
154 m_store.erase( i, m_store.end() );
155 }
156 }
157 catch ( ... ) { }
158 return m_store.size();
159 }
160
162 long DataSvcHelpers::RegistryEntry::remove ( const std::string& nam ) {
163 if ( nam[0] != SEPARATOR ) {
164 std::string path = nam;
165 path.insert(path.begin(), SEPARATOR);
166 return remove(path);
167 }
168 // if this object is already present, this is an error....
169 for (Store::iterator i = m_store.begin(); i != m_store.end(); i++ ) {
170 if ( nam == (*i)->name() ) {
171 remove(*i);
172 return StatusCode::SUCCESS;
173 }
174 }
175 return StatusCode::FAILURE;
176 }
177
179 DataSvcHelpers::RegistryEntry* DataSvcHelpers::RegistryEntry::i_add(const std::string& nam) {
180 if ( nam[0] != SEPARATOR ) {
181 std::string path = nam;
182 path.insert(path.begin(), SEPARATOR);
183 return i_add(path);
184 }
185 // if this object is already present, this is an error....
186 for (Store::iterator i = m_store.begin(); i != m_store.end(); i++ ) {
187 if ( nam == (*i)->name() ) {
188 return 0;
189 }
190 }
191 return new RegistryEntry( nam, this );
192 }
193
195 long DataSvcHelpers::RegistryEntry::add( IRegistry* obj ) {
196 try {
197 RegistryEntry* pEntry = CAST_REGENTRY(RegistryEntry*, obj);
198 pEntry->setDataSvc(m_pDataProviderSvc);
199 m_store.push_back(pEntry);
200 pEntry->setParent(this);
201 if ( !pEntry->isSoft() && pEntry->address() != 0 ) {
202 pEntry->address()->setRegistry(pEntry);
203 }
204 }
205 catch ( ... ) {
206 }
207 return m_store.size();
208 }
209
211 long DataSvcHelpers::RegistryEntry::add ( const std::string& name, DataObject* pObject, bool is_soft ) {
212 RegistryEntry* entry = i_add(name);
213 if ( 0 != entry ) {
214 ( is_soft ) ? entry->makeSoft(pObject) : entry->makeHard(pObject);
215 add( entry );
216 return StatusCode::SUCCESS;
217 }
218 return StatusCode::FAILURE;
219 }
220
222 long DataSvcHelpers::RegistryEntry::add ( const std::string& name, IOpaqueAddress* pAddress, bool is_soft ) {
223 RegistryEntry* entry = i_add(name);
224 if ( 0 != entry ) {
225 ( is_soft ) ? entry->makeSoft(pAddress) : entry->makeHard(pAddress);
226 add( entry );
227 return StatusCode::SUCCESS;
228 }
229 return StatusCode::FAILURE;
230 }
231
233 long DataSvcHelpers::RegistryEntry::deleteElements() {
234 for (Store::iterator i = m_store.begin(); i != m_store.end(); i++ ) {
235 RegistryEntry* entry = CAST_REGENTRY(RegistryEntry*, *i);
236 if ( 0 != entry ) {
237 entry->deleteElements();
238 entry->release();
239 }
240 }
241 m_store.erase(m_store.begin(), m_store.end());
242 return 0;
243 }
244
246 IRegistry* DataSvcHelpers::RegistryEntry::i_find( const IRegistry* obj ) const {
247 Store::const_iterator i = std::find(m_store.begin(),m_store.end(),obj);
248 return (i==m_store.end()) ? 0 : (*i);
249 }
250
252 DataSvcHelpers::RegistryEntry* DataSvcHelpers::RegistryEntry::i_find(const std::string& path) const {
253 if ( path[0] != SEPARATOR ) {
254 std::string thePath = path;
255 thePath.insert(thePath.begin(), SEPARATOR);
256 return i_find(thePath);
257 }
258 else {
259 std::string::size_type len = path.length();
260 std::string::size_type loc1 = path.find(SEPARATOR,1);
261 std::string::size_type len2 = loc1 != std::string::npos ? loc1 : len;
262 for (Store::const_iterator i = m_store.begin(); i != m_store.end(); i++ ) {
263 RegistryEntry* regEnt = CAST_REGENTRY(RegistryEntry*, *i);
264 const std::string& nam = regEnt->name();
265 // check that the first len2 chars of path are the same as nam
266 // (i.e. match {len2:3 nam:"/Ab" path:"/Ab/C"}
267 // but not {len2:3 nam:"/Abc" path:"/Ab/C"})
268 if ( path.compare(0, len2, nam) == 0 ) {
269 try {
270 if ( loc1 != std::string::npos ) {
271 std::string search_path(path, loc1, len);
272 IRegistry* pDir = regEnt->find(search_path);
273 if ( 0 != pDir ) {
274 return CAST_REGENTRY(RegistryEntry*, pDir);
275 }
276 return 0;
277 }
278 else {
279 return CAST_REGENTRY(RegistryEntry*, *i);
280 }
281 }
282 catch (...) {
283 }
284 }
285 }
286 // If this node is "/NodeA", this part allows to find "/NodeA/NodeB" as
287 // our "/NodeB" child.
288 if ( path.compare(0, len2, m_path) == 0 ) {
289 if (len2 < len) {
290 std::string search_path(path, loc1, len);
291 return i_find(search_path);
292 }
293 }
294 }
295 return 0;
296 }
297
299 DataSvcHelpers::RegistryEntry* DataSvcHelpers::RegistryEntry::i_find(const DataObject* key) const {
300 if ( 0 != key ) {
301 if ( key == m_pObject ) {
302 return const_cast<RegistryEntry*>(this);
303 }
304 // Look in the immediate level:
305 RegistryEntry *result = CAST_REGENTRY(RegistryEntry*, i_find(key->registry()));
306 if ( 0 != result ) return result;
307 // Go levels down
308 for (Store::const_iterator i = m_store.begin(); i != m_store.end(); i++ ) {
309 try {
310 const RegistryEntry *entry = CAST_REGENTRY(RegistryEntry*, *i);
311 if( 0 != (result = entry->i_find(key)) )
312 return result;
313 }
314 catch ( ... ) { }
315 }
316 }
317 return 0;
318 }
319
320 // Traverse registry tree
321 long DataSvcHelpers::RegistryEntry::traverseTree(IDataStoreAgent* pAgent, int level) {
322 bool go_down = pAgent->analyse(this, level);
323 long status = StatusCode::SUCCESS;
324 if ( go_down ) {
325 for ( Store::iterator i = m_store.begin(); i != m_store.end(); i++ ) {
326 try {
327 RegistryEntry* entry = CAST_REGENTRY(RegistryEntry*, *i);
328 entry->traverseTree(pAgent, level+1);
329 }
330 catch (...) {
331 status = StatusCode::FAILURE;
332 }
333 }
334 }
335 return status;
336 }
337
338 // Recursive helper to assemble the full path name of the entry
339 void DataSvcHelpers::RegistryEntry::assemblePath(std::string& buffer) const {
340 if ( m_pParent != 0 ) {
341 m_pParent->assemblePath(buffer);
342 }
343 buffer += m_path;
344 }