| The Gaudi Framework v29r1 (5cd95fa2)

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

- File List
- File Members

RegistryEntry.cpp
Go to the documentation of this file.
1 //====================================================================
2 // RegistryEntry.cpp
3 //--------------------------------------------------------------------
4 //
5 // Package : DataSvc ( The LHCb Offline System)
6 //
7 // Description: implementation of the Transient data store
8 //
9 // Author : M.Frank
10 // History :
11 // +---------+----------------------------------------------+---------
12 // | Date | Comment | Who
13 // +---------+----------------------------------------------+---------
14 // | 29/10/98| Initial version | MF
15 // | 03/02/99| Protect dynamic_cast with try-catch clauses | MF
16 // +---------+----------------------------------------------+---------
17 //
18 //====================================================================
19 #define DATASVC_REGISTRYENTRY_CPP
20
21 // STL include files
22 #include <algorithm>
23
24 // Interfaces
25 #include "GaudiKernel/IDataStoreAgent.h"
26 #include "GaudiKernel/IOpaqueAddress.h"
27
28 // Framework include files
29 #include "GaudiKernel/DataObject.h"
30 #include "GaudiKernel/RegistryEntry.h"
31
32 // If you absolutely need optimization: switch off dynamic_cast.
33 // This improves access to the data store roughly by more than 10 %
34 // for balanced trees.
35 //
36 // M.Frank
37 //
38 #define CAST_REGENTRY( x, y ) dynamic_cast<x>( y )
39 //#define CAST_REGENTRY(x,y) (x)(y)
40 constexpr char SEPARATOR{'/'};
41
43 DataSvcHelpers::RegistryEntry::RegistryEntry( std::string path, RegistryEntry* parent )
44 : m_path( std::move( path ) ), m_pParent( parent )
45 {
46 std::string::size_type sep = m_path.rfind( SEPARATOR );
47 if ( m_path.front() != SEPARATOR ) m_path.insert( 0, 1, SEPARATOR );
48 if ( sep != std::string::npos ) m_path.erase( 0, sep );
49 assemblePath( m_fullpath );
50 addRef();
51 }
52
54 DataSvcHelpers::RegistryEntry::~RegistryEntry()
55 {
56 deleteElements();
57 if ( m_pObject ) {
58 if ( !m_isSoft ) m_pObject->setRegistry( nullptr );
59 m_pObject->release();
60 }
61 if ( m_pAddress ) {
62 if ( !m_isSoft ) m_pAddress->setRegistry( nullptr );
63 m_pAddress->release();
64 }
65 }
66
68 unsigned long DataSvcHelpers::RegistryEntry::release()
69 {
70 unsigned long cnt = --m_refCount;
71 if ( !m_refCount ) delete this;
72 return cnt;
73 }
74
76 void DataSvcHelpers::RegistryEntry::setParent( RegistryEntry* pParent )
77 {
78 m_pParent = pParent;
79 m_fullpath.clear();
80 assemblePath( m_fullpath );
81 }
82
84 void DataSvcHelpers::RegistryEntry::makeSoft( DataObject* pObject )
85 {
86 m_isSoft = true;
87 setObject( pObject );
88 // if ( 0 != m_pObject ) { // Useless: This justs sets my own address again...
89 // setAddress(m_pObject->address());
90 // }
91 }
92
94 void DataSvcHelpers::RegistryEntry::makeSoft( IOpaqueAddress* pAddress )
95 {
96 m_isSoft = true;
97 setAddress( pAddress );
98 }
99
101 void DataSvcHelpers::RegistryEntry::makeHard( DataObject* pObject )
102 {
103 makeSoft( pObject );
104 m_isSoft = false;
105 if ( m_pObject ) m_pObject->setRegistry( this );
106 if ( m_pAddress ) m_pAddress->setRegistry( this );
107 }
108
110 void DataSvcHelpers::RegistryEntry::makeHard( IOpaqueAddress* pAddress )
111 {
112 m_isSoft = false;
113 setAddress( pAddress );
114 }
115
117 void DataSvcHelpers::RegistryEntry::setAddress( IOpaqueAddress* pAddress )
118 {
119 if ( pAddress ) {
120 pAddress->addRef();
121 pAddress->setRegistry( this );
122 }
123 if ( m_pAddress ) m_pAddress->release();
124 m_pAddress = pAddress;
125 }
126
128 void DataSvcHelpers::RegistryEntry::setObject( DataObject* pObject )
129 {
130 if ( pObject ) {
131 pObject->addRef();
132 if ( !isSoft() ) pObject->setRegistry( this );
133 }
134 if ( m_pObject ) m_pObject->release();
135 m_pObject = pObject;
136 }
137
139 long DataSvcHelpers::RegistryEntry::remove( IRegistry* obj )
140 {
141 try {
142 RegistryEntry* pEntry = dynamic_cast<RegistryEntry*>( obj );
143 auto i = std::remove( std::begin( m_store ), std::end( m_store ), pEntry );
144 if ( i != std::end( m_store ) ) {
145 pEntry->release();
146 m_store.erase( i, std::end( m_store ) );
147 }
148 } catch ( ... ) {
149 }
150 return m_store.size();
151 }
152
154 long DataSvcHelpers::RegistryEntry::remove( const std::string& nam )
155 {
156 if ( nam.front() != SEPARATOR ) return remove( SEPARATOR + nam );
157 // if this object is already present, this is an error....
158 for ( auto& i : m_store ) {
159 if ( nam == i->name() ) {
160 remove( i );
161 return StatusCode::SUCCESS;
162 }
163 }
164 return StatusCode::FAILURE;
165 }
166
168 DataSvcHelpers::RegistryEntry* DataSvcHelpers::RegistryEntry::i_create( std::string nam )
169 {
170 if ( nam.front() != SEPARATOR ) nam.insert( 0, 1, SEPARATOR );
171 // if this object is already present, this is an error....
172 auto not_present =
173 std::none_of( std::begin( m_store ), std::end( m_store ), [&]( IRegistry* i ) { return nam == i->name(); } );
174 return not_present ? new RegistryEntry( std::move( nam ), this ) : nullptr;
175 }
176
178 long DataSvcHelpers::RegistryEntry::add( IRegistry* obj )
179 {
180 RegistryEntry* pEntry = CAST_REGENTRY( RegistryEntry*, obj );
181 return i_add( pEntry );
182 }
183
185 long DataSvcHelpers::RegistryEntry::i_add( RegistryEntry* pEntry )
186 {
187 // TODO: if this is the sole place where items are added to m_store,
188 // and we know here that they must be RegisteryEntry, can we
189 // drop the dynamic_cast every where else???
190 // TODO: if so, can we also change m_store to be std::vector<RegistryEntry*>
191 // instead
192 // TODO: if so, can we not make it std::vector<RegistryEntry> instead?
193 // TODO: if so, should make sure that a RegistryEntry can be std::move'ed
194 try {
195 pEntry->setDataSvc( m_pDataProviderSvc );
196 m_store.push_back( pEntry );
197 pEntry->setParent( this );
198 if ( !pEntry->isSoft() && pEntry->address() ) {
199 pEntry->address()->setRegistry( pEntry );
200 }
201 } catch ( ... ) {
202 }
203 return m_store.size();
204 }
205
207 long DataSvcHelpers::RegistryEntry::add( const std::string& name, DataObject* pObject, bool is_soft )
208 {
209 RegistryEntry* entry = i_create( name );
210 if ( !entry ) return StatusCode::FAILURE;
211 ( is_soft ) ? entry->makeSoft( pObject ) : entry->makeHard( pObject );
212 i_add( entry );
213 return StatusCode::SUCCESS;
214 }
215
217 long DataSvcHelpers::RegistryEntry::add( const std::string& name, IOpaqueAddress* pAddress, bool is_soft )
218 {
219 RegistryEntry* entry = i_create( name );
220 if ( !entry ) return StatusCode::FAILURE;
221 ( is_soft ) ? entry->makeSoft( pAddress ) : entry->makeHard( pAddress );
222 i_add( entry );
223 return StatusCode::SUCCESS;
224 }
225
227 long DataSvcHelpers::RegistryEntry::deleteElements()
228 {
229 for ( auto& i : m_store ) {
230 RegistryEntry* entry = CAST_REGENTRY( RegistryEntry*, i );
231 if ( entry ) {
232 entry->deleteElements();
233 entry->release();
234 }
235 }
236 m_store.erase( m_store.begin(), m_store.end() );
237 return 0;
238 }
239
241 IRegistry* DataSvcHelpers::RegistryEntry::i_find( const IRegistry* obj ) const
242 {
243 auto i = std::find( m_store.begin(), m_store.end(), obj );
244 return ( i != m_store.end() ) ? ( *i ) : nullptr;
245 }
246
248 DataSvcHelpers::RegistryEntry* DataSvcHelpers::RegistryEntry::i_find( boost::string_ref path ) const
249 {
250 if ( path.front() == SEPARATOR ) path.remove_prefix( 1 ); // strip leading '/', if present
251 while ( !path.empty() ) {
252 // check that the chars of path prior to / are the same as regEnt->name()
253 // (i.e. match { nam:"/Ab" path:"/Ab/C"}
254 // but not { nam:"/Abc" path:"/Ab/C"})
255 auto loc1 = path.find( SEPARATOR );
256 auto cpath = path.substr( 0, loc1 );
257 if ( loc1 != boost::string_ref::npos ) {
258 path.remove_prefix( loc1 + 1 );
259 } else {
260 path.clear();
261 }
262 auto i = std::find_if( std::begin( m_store ), std::end( m_store ), [&]( decltype( m_store )::const_reference reg ) {
263 return cpath == boost::string_ref{reg->name()}.substr( 1 );
264 } );
265 if ( i != std::end( m_store ) ) {
266 RegistryEntry* regEnt = CAST_REGENTRY( RegistryEntry*, *i );
267 return path.empty() ? regEnt : regEnt->i_find( path );
268 }
269 // If this node is "/NodeA", this part allows to find "/NodeA/NodeB" as
270 // our "/NodeB" child.
271 if ( cpath != boost::string_ref{m_path}.substr( 1 ) ) break;
272 }
273 return nullptr;
274 }
275
277 DataSvcHelpers::RegistryEntry* DataSvcHelpers::RegistryEntry::i_find( const DataObject* key ) const
278 {
279 if ( key ) {
280 if ( key == m_pObject ) {
281 return const_cast<RegistryEntry*>( this );
282 }
283 // Look in the immediate level:
284 RegistryEntry* result = CAST_REGENTRY( RegistryEntry*, i_find( key->registry() ) );
285 if ( result ) return result;
286 // Go levels down
287 for ( const auto& i : m_store ) {
288 try {
289 const RegistryEntry* entry = CAST_REGENTRY( RegistryEntry*, i );
290 result = entry->i_find( key );
291 if ( result ) return result;
292 } catch ( ... ) {
293 }
294 }
295 }
296 return nullptr;
297 }
298
299 // Traverse registry tree
300 long DataSvcHelpers::RegistryEntry::traverseTree( IDataStoreAgent* pAgent, int level )
301 {
302 bool go_down = pAgent->analyse( this, level );
303 long status = StatusCode::SUCCESS;
304 if ( go_down ) {
305 for ( auto& i : m_store ) {
306 try {
307 RegistryEntry* entry = CAST_REGENTRY( RegistryEntry*, i );
308 entry->traverseTree( pAgent, level + 1 );
309 } catch ( ... ) {
310 status = StatusCode::FAILURE;
311 }
312 }
313 }
314 return status;
315 }
316
317 // Recursive helper to assemble the full path name of the entry
318 void DataSvcHelpers::RegistryEntry::assemblePath( std::string& buffer ) const
319 {
320 if ( m_pParent ) m_pParent->assemblePath( buffer );
321 buffer += m_path;
322 }
StatusCode::SUCCESS
Definition: StatusCode.h:31
DataSvcHelpers::RegistryEntry::deleteElements
virtual long deleteElements()
Delete all contained elements.
Definition: RegistryEntry.cpp:227
GaudiPython.HistoUtils.path
path
Definition: HistoUtils.py:895
SEPARATOR
constexpr char SEPARATOR
Definition: RegistryEntry.cpp:40
StatusCode::FAILURE
Definition: StatusCode.h:31
DataSvcHelpers::RegistryEntry::name
const std::string & name() const override
Retrieve name of the entry.
Definition: RegistryEntry.h:116
std::string::front
T front(T...args)
IDataStoreAgent::analyse
virtual bool analyse(IRegistry *pObject, int level)=0
Analyse the data object.
DataSvcHelpers::RegistryEntry::addRef
unsigned long addRef() override
IInterface implementation: Dereference the object.
Definition: RegistryEntry.h:114
DataSvcHelpers::RegistryEntry::add
virtual long add(const std::string &name, DataObject *pObject, bool is_soft=false)
Add entry to data store.
Definition: RegistryEntry.cpp:207
std::string::rfind
T rfind(T...args)
DataSvcHelpers::RegistryEntry::m_pParent
RegistryEntry * m_pParent
Pointer to parent.
Definition: RegistryEntry.h:59
DataSvcHelpers::RegistryEntry::traverseTree
virtual long traverseTree(IDataStoreAgent *pAgent, int level=0)
traverse data tree
Definition: RegistryEntry.cpp:300
DataSvcHelpers::RegistryEntry::~RegistryEntry
~RegistryEntry() override
Standard Destructor.
Definition: RegistryEntry.cpp:54
std
STL namespace.
DataObject::setRegistry
void setRegistry(IRegistry *pRegistry)
Set pointer to Registry.
Definition: DataObject.h:70
DataSvcHelpers::RegistryEntry::release
unsigned long release() override
IInterface implementation: Reference the object.
Definition: RegistryEntry.cpp:68
CAST_REGENTRY
#define CAST_REGENTRY(x, y)
Definition: RegistryEntry.cpp:38
IRegistry::name
virtual const name_type & name() const =0
Name of the directory (or key)
std::end
T end(T...args)
IOpaqueAddress::release
virtual unsigned long release()=0
release reference to object
DataSvcHelpers::RegistryEntry::remove
virtual long remove(const std::string &name)
Remove an entry from the store.
Definition: RegistryEntry.cpp:154
std::remove
T remove(T...args)
DataSvcHelpers::RegistryEntry::setAddress
void setAddress(IOpaqueAddress *pAddress) override
Set/Update Opaque address.
Definition: RegistryEntry.cpp:117
DataObject::registry
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:72
DataSvcHelpers::RegistryEntry::i_add
long i_add(RegistryEntry *entry)
Internal method to add entries.
Definition: RegistryEntry.cpp:185
std::string
STL class.
DataSvcHelpers::RegistryEntry::m_fullpath
std::string m_fullpath
String containing full path of the object (volatile)
Definition: RegistryEntry.h:55
DataSvcHelpers::RegistryEntry::assemblePath
void assemblePath(std::string &buffer) const
The following entries serve two aspects: 1) They are faster for recursive calls, because they are non...
Definition: RegistryEntry.cpp:318
DataSvcHelpers::RegistryEntry::isSoft
virtual bool isSoft() const
Is the link soft or hard.
Definition: RegistryEntry.h:128
std::vector::push_back
T push_back(T...args)
DataSvcHelpers::RegistryEntry::setParent
void setParent(RegistryEntry *pParent)
Set new parent pointer.
Definition: RegistryEntry.cpp:76
DataObject::addRef
virtual unsigned long addRef()
Add reference to object.
Definition: DataObject.cpp:59
DataSvcHelpers::RegistryEntry::setObject
void setObject(DataObject *obj)
Set/Update object address.
Definition: RegistryEntry.cpp:128
std::string::erase
T erase(T...args)
DataSvcHelpers::RegistryEntry::m_pDataProviderSvc
IDataProviderSvc * m_pDataProviderSvc
Pointer to hosting transient store.
Definition: RegistryEntry.h:65
DataSvcHelpers::RegistryEntry::setDataSvc
void setDataSvc(IDataProviderSvc *s)
Set the transient data store.
Definition: RegistryEntry.h:90
IRegistry
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
std::string::clear
T clear(T...args)
DataSvcHelpers::RegistryEntry::address
IOpaqueAddress * address() const override
Retrieve opaque storage address.
Definition: RegistryEntry.h:124
DataSvcHelpers::RegistryEntry::m_pAddress
IOpaqueAddress * m_pAddress
Pointer to opaque address (load info)
Definition: RegistryEntry.h:61
DataSvcHelpers::RegistryEntry::makeSoft
void makeSoft(DataObject *pObject)
Initialize link as soft link.
Definition: RegistryEntry.cpp:84
DataSvcHelpers::RegistryEntry::i_create
RegistryEntry * i_create(std::string name)
Internal method to create entries.
Definition: RegistryEntry.cpp:168
IDataStoreAgent.h
std::move
T move(T...args)
DataSvcHelpers::RegistryEntry::m_isSoft
bool m_isSoft
Is the link soft or hard?
Definition: RegistryEntry.h:53
IOpaqueAddress.h
RegistryEntry.h
DataSvcHelpers::RegistryEntry
Definition of an entry in the transient data store.
Definition: RegistryEntry.h:36
DataObject::release
virtual unsigned long release()
release reference to object
Definition: DataObject.cpp:51
std::string::insert
T insert(T...args)
DataSvcHelpers::RegistryEntry::m_pObject
DataObject * m_pObject
Pointer to object.
Definition: RegistryEntry.h:63
std::find
T find(T...args)
DataSvcHelpers::RegistryEntry::m_refCount
unsigned long m_refCount
Reference counter.
Definition: RegistryEntry.h:51
std::vector::size
T size(T...args)
IDataStoreAgent
Generic data agent interface.
Definition: IDataStoreAgent.h:16
std::begin
T begin(T...args)
std::none_of
T none_of(T...args)
DataSvcHelpers::RegistryEntry::m_store
Store m_store
Store of leaves.
Definition: RegistryEntry.h:67
DataSvcHelpers::RegistryEntry::RegistryEntry
RegistryEntry(std::string path, RegistryEntry *parent=nullptr)
Standard Constructor.
Definition: RegistryEntry.cpp:43
DataSvcHelpers::RegistryEntry::m_path
std::string m_path
Path name.
Definition: RegistryEntry.h:57
std::string::substr
T substr(T...args)
gaudirun.level
level
Definition: gaudirun.py:271
IOpaqueAddress::setRegistry
virtual void setRegistry(IRegistry *r)=0
Update directory pointer.
IOpaqueAddress
Opaque address interface definition.
Definition: IOpaqueAddress.h:23
DataObject
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:29
DataSvcHelpers::RegistryEntry::i_find
IRegistry * i_find(const IRegistry *pDirectory) const
Internal method to retrieve data directory.
Definition: RegistryEntry.cpp:241
DataObject.h
IOpaqueAddress::addRef
virtual unsigned long addRef()=0
Add reference to object.
DataSvcHelpers::RegistryEntry::makeHard
void makeHard(DataObject *pObject)
Initialize link as hard link.
Definition: RegistryEntry.cpp:101