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
28 
29 // Framework include files
30 #include "GaudiKernel/DataObject.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 
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  }
62  addRef();
63 }
64 
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 
80  unsigned long cnt = --m_refCount;
81  if ( 0 == m_refCount ) {
82  delete this;
83  }
84  return cnt;
85 }
86 
89  m_pParent = pParent;
90  m_fullpath = "";
91  assemblePath(m_fullpath);
92 }
93 
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 
105  m_isSoft = true;
106  setAddress(pAddress);
107 }
108 
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 
123  m_isSoft = false;
124  setAddress(pAddress);
125 }
126 
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 
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 
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 
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 
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 
234  for (Store::iterator i = m_store.begin(); i != m_store.end(); 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 
247  Store::const_iterator i = std::find(m_store.begin(),m_store.end(),obj);
248  return (i==m_store.end()) ? 0 : (*i);
249 }
250 
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++ ) {
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 
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
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 {
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 }
virtual unsigned long addRef()
IInterface implementation: Dereference the object.
virtual long deleteElements()
Delete all contained elements.
virtual bool analyse(IRegistry *pObject, int level)=0
Analyse the data object.
virtual long add(const std::string &name, DataObject *pObject, bool is_soft=false)
Add entry to data store.
virtual long traverseTree(IDataStoreAgent *pAgent, int level=0)
traverse data tree
void setRegistry(IRegistry *pRegistry)
Set pointer to Registry.
Definition: DataObject.h:65
#define CAST_REGENTRY(x, y)
virtual long remove(const std::string &name)
Remove an entry from the store.
virtual unsigned long release()
IInterface implementation: Reference the object.
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:69
std::string m_fullpath
String containing full path of the object (volatile)
Definition: RegistryEntry.h:48
void assemblePath(std::string &buffer) const
The following entries serve two aspects: 1) They are faster for recursive calls, because they are non...
virtual bool isSoft() const
Is the link soft or hard.
Seperator
void setParent(RegistryEntry *pParent)
Set new parent pointer.
virtual unsigned long addRef()
Add reference to object.
Definition: DataObject.cpp:53
void setObject(DataObject *obj)
Set/Update object address.
virtual IOpaqueAddress * address() const
Retrieve opaque storage address.
def remove
Definition: install.py:153
void setDataSvc(IDataProviderSvc *s)
Set the transient data store.
Definition: RegistryEntry.h:81
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
void makeSoft(DataObject *pObject)
Initialize link as soft link.
void setAddress(IOpaqueAddress *pAddress)
Set/Update Opaque address.
GAUDI_API std::string path(const AIDA::IBaseHistogram *aida)
get the path in THS for AIDA histogram
RegistryEntry(const std::string &path, RegistryEntry *parent=0)
Standard Constructor.
Definition of an entry in the transient data store.
Definition: RegistryEntry.h:34
const std::string & name() const
Retrieve name of the entry.
Generic data agent interface.
std::string m_path
Path name.
Definition: RegistryEntry.h:50
virtual ~RegistryEntry()
Standard Destructor.
virtual void setRegistry(IRegistry *r)=0
Update directory pointer.
Opaque address interface definition.
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:31
list i
Definition: ana.py:128
virtual IRegistry * find(const IRegistry *obj) const
Try to find an object identified by its pointer.
IRegistry * i_find(const IRegistry *pDirectory) const
Internal method to retrieve data directory.
RegistryEntry * i_add(const std::string &name)
Internal method to add entries.
virtual unsigned long addRef()=0
Add reference to object.
void makeHard(DataObject *pObject)
Initialize link as hard link.